Java中volatile关键字的作用
在Java的多线程工作模式下,每一个线程都有自己的一个内存空间,在对实际的变量进行修改时,每一个线程需要先把主内存内的变量拷贝到自己的内存空间中,在拷贝完成后,再进行修改,最后再把修改后的变量放回到主内存中。
但是如果同时有多个线程对同一个变量进行修改操作,如上图所示,假如A线程和B线程同时把变量i拷贝到自己的内存空间中,进行修改,假如同时减1,则再将修改后的i放回到主内存时,实际i只变化了一次,达不到多线程的效果。
测试一
看一下如下的代码,是没有使用volatile关键字做同步的
class Resource implements Runnable {
public int i;
public Resource(int _i){
i = _i;
}
public void run(){
while(true){
if (i>0){
i--;
System.out.println(Thread.
currentThread().getName()+" "+i);
}
else{
System.out.println(Thread.
currentThread().getName());
break;
}
}
}
}
public class TestPriority{
public static void main(String[] args){
Resource m = new Resource(100);
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
这个程序的目的是使用两个线程,来对同一个变量i进行操作,使其从100不断减少到0,并打印中间值,在本程序中,i并没有使用volatile关键字进行修饰,其部分运行结果如下: 可以看到,其中有些中间值被输出了两次,原因就是同时对变量i做了修改。
测试二
测试二相比较测试一的代码改动为:i变量用volatile关键字进行了修饰 运行结果如下 可以看到是没有冲突的
总结
volatile关键字可以保证内存中变量的可见性,可以让每一个线程知道变量最新的值,当一个共享变量被volatile修饰时,它会保证修改的值立即被更新到主存中。
|