上QQ阅读APP看书,第一时间看更新
2.2.9 多个锁就是异步执行
如果Service.java文件代码更改如下:
package service; public class Service { private String usernameParam; private String passwordParam; public void setUsernamePassword(String username, String password) { try { String anyString = new String(); synchronized (anyString) { System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入同步块"); usernameParam = username; Thread.sleep(3000); passwordParam = password; System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开同步块"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
程序运行效果如图2-30所示。
图2-30 不是同步的而是异步,因为不是同一个锁
可见,想使用“synchronized(非this对象x)同步代码块”格式进行同步操作时,锁必须是同一个,如果不是同一个,运行的结果就是异步调用,交叉运行了。
下面再用另外一个项目来验证使用“synchronized(非this对象x)同步代码块”格式时持有不同的锁是异步的效果。
创建新的项目,名称为synBlockString2,验证synchronized(非this对象)与同步synchronized方法是异步调用。
两个自定义线程类代码如图2-31所示。
类Service.java代码如下:
package extobject; public class MyObject { synchronized public void methodA() { try { System.out.println("begin methodA threadName=" + Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("end endTime=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } public void methodB() { try { System.out.println("begin methodB threadName=" + Thread.currentThread().getName() + " begin time=" + System.currentTimeMillis()); Thread.sleep(5000); System.out.println("end"); } catch (InterruptedException e) { e.printStackTrace(); } } }
图2-31 线程类代码
类Run.java代码如下:
package test.run; import extobject.MyObject; import extthread.ThreadA; import extthread.ThreadB; public class Run { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); a.setName("A"); ThreadB b = new ThreadB(object); b.setName("B"); a.start(); b.start(); } }
程序运行结果如图2-32所示。
图2-32 异步运行效果
由于锁不同,所以运行结果就是异步的。