标签:
这一章节我们讨论一下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"); } }
输出:
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
从头认识多线程-3.3 synchronized某些解决不了的可视性问题,只能使用volatile来解决
标签:
原文地址:http://blog.csdn.net/raylee2007/article/details/51605199