上QQ阅读APP看书,第一时间看更新
1.11.8 使用stop()释放锁导致数据结果不一致
本节将讲解使用stop()释放锁给数据造成不一致性的结果,如果出现这样的情况,程序处理的数据完全有可能遭到破坏,最终导致程序执行的流程是错误的,在此一定要注意。下面来看一个示例。
创建项目stopThrowLock,文件MyService.java代码如下:
package service; public class MyService { private String username = "a"; private String password = "aa"; synchronized public String getUsername() { return username; } synchronized public String getPassword() { return password; } synchronized public void printString(String username, String password) { try { this.username = username; Thread.sleep(100000000); this.password = password; } catch (InterruptedException e) { e.printStackTrace(); } } }
调用业务方法printString()的线程代码如下:
package extthread; import service.MyService; public class MyThreadA extends Thread { private MyService object; public MyThreadA(MyService object) { super(); this.object = object; } @Override public void run() { object.printString("b", "bb"); } }
输出数据的线程代码如下:
package extthread; import service.MyService; public class MyThreadB extends Thread { private MyService object; public MyThreadB(MyService object) { super(); this.object = object; } @Override public void run() { System.out.println(object.getUsername() + " " + object.getPassword()); System.out.println(" end " + System.currentTimeMillis()); } }
文件Run.java代码如下:
package test; import extthread.MyThreadA; import extthread.MyThreadB; import service.MyService; public class Run { public static void main(String[] args) throws InterruptedException { MyService service = new MyService(); MyThreadA myThreadA = new MyThreadA(service); MyThreadB myThreadB = new MyThreadB(service); myThreadA.start(); Thread.sleep(500); myThreadB.start(); System.out.println("begin " + System.currentTimeMillis()); Thread.sleep(5000); myThreadA.stop(); } }
程序运行结果如图1-52所示。
图1-52 强制stop造成数据不一致
当执行stop()方法后MyThreadA才会释放锁,线程MyThreadB才能执行同步的get()方法,并且synchronized同步的getUsername()和getPassword()方法取出的是未处理完成的半成品错误数据。
由于stop()方法已经在JDK中被标为“作废/过期”的方法,显然它在功能上具有缺陷,所以不建议在程序中使用stop()方法停止线程。