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所示。
图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所示。
图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所示。
图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(); } }
图2-40 自定义线程代码
程序运行结果如图2-41所示。
图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所示。
图2-42 同样也是同步效果