![Java多线程编程核心技术(第3版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/745/42637745/b_42637745.jpg)
2.2.12 细化验证3个结论
synchronized(非this对象x)表示将x对象本身作为“对象监视器”,这样就可以分析出3个结论。
□当多个线程同时执行synchronized(x){}同步代码块时呈同步效果。
□当其他线程执行x对象中synchronized同步方法时呈同步效果。
□当其他线程执行x对象方法里面的synchronized(this)代码块时也呈现同步效果。
注意
如果其他线程调用不加synchronized关键字的方法时还是异步调用。
为了验证这3个结论,创建实验项目synchronizedBlockLockAll。
先来验证第1个结论:当多个线程同时执行synchronized(x){}同步代码块时呈同步效果。
创建名称为test1的包。类MyObject.java代码如下:
package test1.extobject; public class MyObject { }
类Service.java代码如下:
package test1.service; import test1.extobject.MyObject; public class Service { public void testMethod1(MyObject object) { synchronized (object) { try { System.out.println("testMethod1 ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); Thread.sleep(2000); System.out.println("testMethod1 releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
两个自定义线程代码如图2-37所示。
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-37.jpg?sign=1739305577-DACAt1vsDpicTAVwdfWQwqOz7BPAtlKk-0-49243fe463bd1e83b36b9b5c568d9cda)
图2-37 线程代码
类文件Run1_1.java代码如下:
package test1.run; import test1.extobject.MyObject; import test1.extthread.ThreadA; import test1.extthread.ThreadB; import test1.service.Service; public class Run1_1 { public static void main(String[] args) { Service service = new Service(); MyObject object = new MyObject(); ThreadA a = new ThreadA(service, object); a.setName("a"); a.start(); ThreadB b = new ThreadB(service, object); b.setName("b"); b.start(); } }
程序运行结果如图2-38所示。
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-38.jpg?sign=1739305577-8YWa4iz00YPgGTPdntA2RS164lrVyjTC-0-fb52530c0955b5d36336cf521c6b5a34)
图2-38 同步效果
同步的原因是使用同一把锁,如果使用不同的锁会出现什么样的效果呢?
创建类文件Run1_2.java,代码如下:
package test1.run; import test1.extobject.MyObject; import test1.extthread.ThreadA; import test1.extthread.ThreadB; import test1.service.Service; public class Run1_2 { public static void main(String[] args) { Service service = new Service(); MyObject object1 = new MyObject(); MyObject object2 = new MyObject(); ThreadA a = new ThreadA(service, object1); a.setName("a"); a.start(); ThreadB b = new ThreadB(service, object2); b.setName("b"); b.start(); } }
程序执行结果如图2-39所示。
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-39.jpg?sign=1739305577-M0DFfn6lRhisk6OtIwpXsDGqULgNfkfa-0-8f54e83d59e169b1df6546d142b93232)
图2-39 异步调用,因为是不同的锁
继续验证第2个结论:当其他线程执行x对象中的synchronized同步方法时呈同步效果。
创建名称为test2的包。类MyObject.java代码如下:
package test2.extobject; public class MyObject { synchronized public void speedPrintString() { System.out.println("speedPrintString ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); System.out.println("-----------------"); System.out.println("speedPrintString releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } }
类Service.java代码如下:
package test2.service; import test2.extobject.MyObject; public class Service { public void testMethod1(MyObject object) { synchronized (object) { try { System.out.println("testMethod1 ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("testMethod1 releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
两个自定义线程代码如图2-40所示。
类Run.java代码如下:
package test2.run; import test2.extobject.MyObject; import test2.extthread.ThreadA; import test2.extthread.ThreadB; import test2.service.Service; public class Run { public static void main(String[] args) throws InterruptedException { Service service = new Service(); MyObject object = new MyObject(); ThreadA a = new ThreadA(service, object); a.setName("a"); a.start(); Thread.sleep(100); ThreadB b = new ThreadB(object); b.setName("b"); b.start(); } }
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-40.jpg?sign=1739305577-82RAUCo1SgEP1x7wPOcYSPlcoGNgakbG-0-8af1d14461da68c1a1ba1db0c11a8891)
图2-40 自定义线程代码
程序运行结果如图2-41所示。
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-41.jpg?sign=1739305577-bbQrSF90X9H6qV9hA4TK92mrDi9SQOPP-0-c7e87af97e786aeaa142f2b13cce1035)
图2-41 同步效果
继续验证第3个结论:当其他线程执行x对象方法里面的synchronized(this)代码块时也呈现同步效果。
创建名称为test3的包。创建名称为MyObject.java的类,代码如下:
package test3.extobject; public class MyObject { public void speedPrintString() { synchronized (this) { System.out.println("speedPrintString ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); System.out.println("-----------------"); System.out.println("speedPrintString releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } } }
其他代码与test2包中Java类的代码一样,程序运行结果如图2-42所示。
![](https://epubservercos.yuewen.com/204B22/22139293909121606/epubprivate/OEBPS/Images/2-42.jpg?sign=1739305577-9SUoxJ2u2S0qdhvxZpHD9OSgAVhmjR2U-0-9620b554529b2594c24b81d01b0b53d8)
图2-42 同样也是同步效果