Java并发编程之volatile解析

来源:互联网 发布:python magic number 编辑:程序博客网 时间:2024/05/16 19:45

在对该关键字进行认识之前,需要对Java内存模型有一定的认识。
Java内存模型规定了所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的是主内存副本的拷贝,线程对于变量的操作(读取,复制)都必须在工作内存中进行,而不能直接读写主内存中的变量。
这里写图片描述

在进行变量操作的时候,如果每次都是从主内存中读写,无疑是影响性能的,
即一个线程在操作某一个变量之前,会先把变量的值从主内存中拷贝一个副本放到工作内存中,操作完成之后同步到主内存中。不同的线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。


volatile:
当一个变量被定义为volatile(不稳定的)之后,线程在进行变量操作的时候,都不会使用本地内存中之前缓存的数据,而是每次都会从主内存中把变量的值拷贝副本到工作内存中,这样就保证了变量对于所有线程的可见性。

public class TestVolatile {     public static void main(String[] args) throws Exception {         ThreadDemo td=new ThreadDemo();         Thread t=new Thread(td);         t.start();         while(true){             if(td.isFlag()){                 System.out.println("OK");                 break;             }         }    }    }class ThreadDemo implements Runnable{    private volatile boolean flag=false;    @Override    public void run() {        try {            Thread.sleep(2000);         } catch (InterruptedException e) {            e.printStackTrace();        }        flag=true;        System.out.println("flag="+isFlag());    }    public boolean isFlag() {        return flag;    }    public void setFlag(boolean flag) {        this.flag = flag;    }}

需要特别注意的是,
即使volatile能够保证其变量对于线程的可见性,但是却不能保证并发的安全性。
比如多线程执行线程执行i++(i假设用volatilex修饰)也不能保证其安全性。
如下图:
这里写图片描述

因为i++并不是原子性的操作,当一个线程A再工作内存中进行数据操作的时候,还未结束的时候,cpu切换到了另一个线程B,而此时之前i++操作并没有结束,即并没有把数据刷新到主内存中,此时B获取到的数据跟A获取的数据实际上是一样的,这时候就存在了并发的问题了。

Java并发之CAS算法
Java并发之CountDownLatch

原创粉丝点击