浅谈对volatile关键字的理解与举例应用

每个线程都会有各自的线程栈,执行运算的时候,是从公共堆栈读取数据到线程堆栈中,线程操作的是线程堆栈的数据,结束后,再从线程堆栈回刷到公共堆栈,所以这种肯定会引起数据的不同步。volatile关键字保证了在多线程环境下,被修饰的变量在被修改后会立即同步到主存,这样该线程对这个变量的修改就是对所有其他线程可见的,其他线程能够马上读到这个修改后值.  volatile,从字面上说是易变的。事实上,也确实如此,这个关键字的作用就是告诉编译器,只要是被volatil关键字修饰的变量都是易变的、不稳定的。那为什么是易变的呢?因为volatile所修饰的变量是直接存在于主内存中的,线程对变量的操作也是直接反映在主内存中,所以说其是易变的。

public class VolatileThread extends Thread{
	//private volatile boolean isRunning=true;
	private  boolean isRunning=true;
	private void setRunning(boolean isRunning){
		this.isRunning=isRunning;
	}
	
	public void run(){
		System.out.println("进入run方法。。");
		while(isRunning==true){
			
		}
		System.out.println("线程停止");
	}
	
	public static void main(String [] args) throws InterruptedException{
		VolatileThread volatileThread=new VolatileThread();
		volatileThread.start();
		Thread.sleep(1000);
		volatileThread.setRunning(false);
		System.out.println("现在isRunning的值为:"+volatileThread.isRunning);
	}

}

这个时候我们没有对变量isRunning加上volatile关键字,此时的运行结果:

红点会一直在,程序一直运行不完,会停在while里面。需要自己手动点停红点。因为这个时候isRunning不是共享变量,在run中是true所以会进去while循环。但是当我们加上volatile这个关键字以后就会变得不一样。

在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。就像我图里这样:




所以在我们添加关键字后再次执行,结果就会变这样:




发布了93 篇原创文章 · 获赞 36 · 访问量 11万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览