volatile实质简单探究

本人在编写下面代码是遇到了线程关闭不了的问题,最后通过加volatile解决了相关问题,对内部原因在查阅资料后明白类一些

代码如下:

package com.mec.thread_pool.test;

public class TaskRunByThread implements Runnable {
	private static int id;
	private boolean goon;
	private int currentId;
	
	public TaskRunByThread() {
		goon = true;
		currentId = ++id;
		new Thread(this, "Thread-" + currentId).start();
	}
	
	public void stopThread() {
		System.out.println("收到结束线程[" + Thread.currentThread().getName()
				+ "]的命令!");
		goon = false;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "线程开始!");
		while (goon) {
					
		}
		System.out.println(Thread.currentThread().getName() + "线程结束!");
	}
}
package com.mec.thread_pool.test;

public class Test {

	public static void main(String[] args) {
		TaskRunByThread byThread = new TaskRunByThread();
		try {
			Thread.sleep(1000);
			byThread.stopThread();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

通过main()出来的主线程来创造和关闭一个新线程;但是如果goon不加volatiled输出如下:

Thread-1收到main的结束命令,但是Thread-1并没有结束(通过右上角的小红点和输出可以看出来);

这是由于现在CPU的运算速度快速提高,但计算机的IO操作却跟不上计算机的运算速度,所以出现了寄存器以及缓存区,对于计算机某个进程需要多次用到的数据,他会拷贝一份副本放在缓存区里;结构图如下:

越靠近CPU重里面读取数据的速度也就越快,空间也越小;

Thread-1线程在执行时候由于while里面非常简单所以,他会把goon复制一份到缓存区。判断循环是否继续条件的时候他会直接从缓存区中得到goon。而main线程却改变的是RAM中Thread-1数据区的goon。而Thread-1不会区查看RAM中的数据一直执行下去,造成Thread-1关闭不了。

在加上volatile之后,main线程在更改goon的值后,当Thread-1线程使用缓存区中的他自己的goon时,他会发现该变量被标记为失效,他会去和RAM中的goon同步,这样就不会不会出现Thread-1结束不了的情况了。

加上volatile后执行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值