This article introduces the synchronization of synchronized (non-this object x) method, x is generally a parameter or instance variable
Different threads hold different object monitors, the call is asynchronous
package chapter2.synBlockString3; /* Demonstrate that different threads hold different object monitors, and the call is asynchronous * ta's object monitor is anyString, and b's object monitor is a class instance object a begin b begin b end a end */ public class Run { public static void main(String[] args) { Service service=new Service(); ThreadA ta=new ThreadA(service); ThreadB tb=new ThreadB(service); ta.setName("a"); ta.start(); tb.setName("b"); tb.start(); } } package chapter2.synBlockString3; public class Service { private String anyString=new String(); public void a(){ try{ synchronized (anyString) { System.out.println("a begin"); Thread.sleep(3000); System.out.println("a end"); } }catch(InterruptedException e){ e.printStackTrace (); } } synchronized public void b(){ System.out.println("b begin"); System.out.println("b end"); } } package chapter2.synBlockString3; public class ThreadA extends Thread{ private Service service; public ThreadA(Service service) { this.service=service; } @Override public void run() { super.run(); service.a(); } } package chapter2.synBlockString3; public class ThreadB extends Thread{ private Service service; public ThreadB(Service service) { this.service=service; } @Override public void run() { super.run(); service.b(); } }
Three conclusions about the usage of synchronized (non-this object x):
1. When multiple objects execute synchronized(x){} synchronized code blocks at the same time, the effect is synchronized
2. When other objects execute the synchronized method of the x object, the synchronization effect is presented, but if other threads call the non-synchronized method of the x object, it is still asynchronous
3. When other objects execute the synchronized(this) code block in the x object, they are also synchronized
The first two conclusions are relatively obvious, and only the third conclusion is verified:
package chapter2.test3; public class MyObject { public void speedPrintString(){ synchronized (this) { System.out.println("speedPrintString __get locked time="+System.currentTimeMillis()+ "run thread name="+Thread.currentThread().getName()); System.out.println("------------------"); System.out.println("speedPrintString ___release locked time="+System.currentTimeMillis()+ "run thread name="+Thread.currentThread().getName()); } } } package chapter2.test3; /* Demonstrate that when the syn(obj) method is used, the syn(this) code block of other processes entering obj is synchronized, because syn(this) also locks the obj instance * That is, thread b needs to wait for thread a to finish executing syn(obj) and release the lock of obj to obtain the lock of obj. testMethod1 _____get locked time=1525528023801run threadName=a testMethod1 _____release locked time=1525528025801run threadName=a speedPrintString __get locked time=1525528025801run thread name=b ------------------ speedPrintString ___release locked time=1525528025802run thread name=b */ public class Run { public static void main(String[] args) throws InterruptedException { Service sv=new Service(); MyObject mo=new MyObject(); ThreadA ta=new ThreadA(mo, sv); ThreadB tb=new ThreadB(mo); ta.setName("a"); ta.start(); //The main thread is put to sleep here to let the a thread enter the synchronization block first Thread.sleep(100); tb.setName("b"); tb.start(); } } package chapter2.test3; public class Service { public void testMethod1(MyObject obj){ synchronized (obj) { try{ System.out.println("testMethod1 _____get locked time="+System.currentTimeMillis()+ "run threadName="+Thread.currentThread().getName()); Thread.sleep(2000); System.out.println("testMethod1 _____release locked time="+System.currentTimeMillis()+ "run threadName="+Thread.currentThread().getName()); }catch(InterruptedException e){ e.printStackTrace (); } } } } package chapter2.test3; public class ThreadA extends Thread { private MyObject obj; private Service sv; public ThreadA(MyObject obj,Service sv) { super(); this.obj=obj; this.sv=sv; } @Override public void run() { super.run(); sv.testMethod1 (obj); } } package chapter2.test3; public class ThreadB extends Thread { private MyObject obj; public ThreadB(MyObject obj) { super(); this.obj=obj; } @Override public void run() { super.run(); //Call the syn method of obj obj.speedPrintString(); } }
Reference: <java multi-threaded programming core technology>