线程中的静态同步和非静态同步方法

任何人都可以解释声明……“静态同步方法和非静态同步方法不会相互阻塞 – 它们可以同时运行”

静态方法和非静态方法上的锁定对象是不同的。 静态方法使用Class对象作为锁(lock obj: MyClass.class ),而非静态方法使用实例对象作为锁定,此时方法的调用被绑定到该锁(lock obj: this ) 。

 static synchronized void test() { foo(); } 

等于

 static void test() { synchronized(MyClass.class) { foo(); } } 

 synchronized void test() { foo(); } 

等于

 void test() { synchronized(this) { foo(); } } 

这意味着:静态方法锁定类的类对象。 非静态方法锁定它们被调用的实例(默认情况下,也可以synchronized(anyOtherLock) )。 由于它们锁定不同的对象,因此它们不会相互阻挡。

非静态同步方法将监视器锁定在’this’上 – 这意味着只有当前对象被锁定。因此,如果任何一个线程正在访问非静态同步方法,则将阻止与当前对象关联的所有线程访问该类的非静态同步方法。 而其他对象的线程仍然可以访问方法。

静态同步方法将监视器锁定放在Class对象上 – 这意味着如果任何对象的线程正在访问该方法,则所有线程都将被阻止以访问该类的所有静态同步方法。

公共类TestSync {

 public synchronized void n1(int threadId) { snooze(threadId); System.out.println("Sync non static n1 " + threadId); } public void n2(int threadId) { snooze(threadId); System.out.println(" non static n2 " + threadId); } public static synchronized void s1(int threadId) { snooze(threadId); System.out.println("Sync static s1 "+ threadId); } public static void s2(int threadId) { snooze(threadId); System.out.println(" static s2 "+ threadId); } static void snooze(int threadId) { System.out.println("Waiting ... "+ threadId); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { TestSync ob = new TestSync(); TestSync ob2=new TestSync(); TestSync ob3=new TestSync(); TestSync ob4=new TestSync(); Runnable r1=()-> { /*ob.n1(10); ob.n2(10);*/ ob.s1(10); //ob.s2(10); }; Runnable r3=()-> { /*ob2.n1(30); ob2.n2(30);*/ ob2.s1(30); //ob2.s2(30); }; Runnable r4=()-> { /*ob3.n1(40); ob3.n2(40);*/ ob3.s1(30); //ob3.s2(30); }; Thread t1=new Thread(r1); Thread t2= new Thread(r2); Thread t3= new Thread(r3); Thread t4= new Thread(r4); Thread t5= new Thread(r5); t1.start(); t3.start(); t4.start(); } 

运行一次for static synchronized,然后在runnable和run中取消注释非静态同步调用(和注释静态同步)。 你会明白的。