可以,两个线程运行所需资源不同,不需要抢占。
案例一、
package duoxiancheng2;public class Ms1 { //A线程正在执行一个对象中的同步方法,B线程是否可以同时执行同一个对象中的非同步方法? Object a = new Object(); public static void main(String[] args) { var t = new Ms1(); new Thread(() -> t.a1()).start();//A线程 new Thread(() -> t.a2()).start();//B线程 } void a1() { synchronized (a) { System.out.println("同步方法"); } } void a2() { System.out.println("非同步方法"); }}
运行结果:
问题二:同上,B线程是否可以同时执行同一个对象中的另一个同步方法? 不可以,两个线程执行需要一个共同资源,共同资源加了同步锁,同一时刻只能一个线程占用。
案例二、
package duoxiancheng2;import java.util.concurrent.TimeUnit;public class Ms2 { //同上,B线程是否可以同时执行同一个对象中的另一个同步方法? Object a = new Object(); public static void main(String[] args) { var t = new Ms2(); new Thread(() -> t.a1()).start();//A线程 new Thread(() -> t.a2()).start();//B线程 } void a1() { synchronized (a) { System.out.println("进入同步方法1"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("同步方法1结束"); } } void a2() { synchronized (a) { System.out.println("进入同步方法2"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("同步方法2结束"); } }}
运行结果:
线程A先运行,占用资源。
等线程A运行完释放资源后,线程B才可以进入执行
线程B执行完
会,线程出现异常抛出后立刻释放资源。
案例三、
package duoxiancheng2;import java.util.concurrent.TimeUnit;public class Ms3 { //线程抛出异常会释放锁吗? Object a = new Object(); public static void main(String[] args) { var t = new Ms3(); new Thread(() -> t.a1()).start();//A线程 new Thread(() -> t.a2()).start();//B线程 } void a1() { int c = 3; int b; synchronized (a) { System.out.println("进入同步方法1"); try { b = c / 0; System.out.println(b); TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("同步方法1结束"); } } void a2() { synchronized (a) { System.out.println("进入同步方法2"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("同步方法2结束"); } }}
结果:
方法一出现异常,立刻释放资源。线程二开始执行