从头认识多线程-3.3 synchronized某些解决不了的可视性问题,只能使用volatile来解决

这一章节我们讨论一下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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值