这一章节我们讨论一下synchronized某些解决不了的可视性问题。
1.引入之前的异步死循环代码:
package com.ray.deepintothread.ch03.topic_3;
public class DeadForAsychn {
public static void main(String[] args) throws InterruptedException {
MyClassOne myClassOne = new MyClassOne();
myClassOne.start();
Thread.sleep(1000);
myClassOne.setStop(true);
System.out.println("---------stop----------");
}
}
class MyClassOne extends Thread {
private boolean isStop = false;
public boolean isStop() {
return isStop;
}
public void setStop(boolean isStop) {
this.isStop = isStop;
}
@Override
public void run() {
System.out.println("running");
while (!isStop) {
}
System.out.println("out");
}
}
注意:上面的代码必须在-server状态下的jvm才能够出现异步死循环
输出:
running
---------stop----------
(程序依然运行,再也没有输出)
2.之前使用volatile来解决上面的问题,我们这次尝试synchronized
package com.ray.deepintothread.ch03.topic_3;
public class SolutionOfDeadForAsychn {
public static void main(String[] args) throws InterruptedException {
MyClassTwo myClassTwo = new MyClassTwo();
myClassTwo.start();
Thread.sleep(1000);
myClassTwo.setStop(true);
System.out.println("---------stop----------");
}
}
class MyClassTwo extends Thread {
private Boolean isStop = false;
public boolean isStop() {
return isStop;
}
public void setStop(boolean isStop) {
this.isStop = isStop;
}
@Override
public void run() {
synchronized (isStop) {
System.out.println("synchronized");
System.out.println("running");
while (!isStop) {
}
System.out.println("out");
}
}
}
输出:
running
---------stop----------
(程序依然运行,再也没有输出)
从输出结果我们可以看见,还是不行,我们下面将来解释一下为什么?
3.我们从内存模型切入
下面摘自:Java内存模型详解
我们主要使用的是下面几点:
(1) 获取对象监视器的锁(lock)
(2) 清空工作内存数据, 从主存复制变量到当前工作内存, 即同步数据 (read and load)
(3) 执行代码,改变共享变量值 (use and assign)
(4) 将工作内存数据刷回主存 (store and write)
(5) 释放对象监视器的锁 (unlock)
根据上面的图,我们可以判断,其实isStop没有同步到主存里面,它的更新作用域只是在线程内存里面
主要因为,我们的锁一直都没有释放,执行run方法的线程一直没有办法从主存那里更新新的状态,一直都是沿用工作内存里面的状态
也就是说,在run方法里面看到的isStop一直都是false
因此,在上面的这种情况,我们只能够使用volatile强制run方法里面的isStop每一次的获取都是从主内存获取。
总结:这一章节展示了synchronized在特定可视性问题上面的弱势。
这一章节就到这里,谢谢
------------------------------------------------------------------------------------
我的github:https://github.com/raylee2015/DeepIntoThread
目录:http://blog.csdn.net/raylee2007/article/details/51204573