美文网首页
Volatile理解

Volatile理解

作者: MC_Honva | 来源:发表于2018-01-11 15:48 被阅读26次

    volatile作用

    强制线程从公共堆栈中取得变量的值,而不是从线程私有变量中取值,解决变量在多线程之间读取的可见性。具有可见性,可是不具备原子性

    synchronized作用

    保证多个线程资源的同步,具有可见性和原子性,可以保证线程安

    线程安全2个特点
    • 原子性:执行过程中,不会被其他线程打扰
    • 可见性:一个线程修改状态,对其他线程而言是可见的
    volatile原理

    每个线程访问堆中对象时,将堆中对象load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆变量值有任何关系,而是直接修改副本变量值。
    修改完之后,自动把线程变量副本的值写到对象在堆变量中。这样堆中对象的值就产生了变化。这些操作不是原子性的。
    使用volatile修饰变量,JVM只是保证从内存加载到线程工作内存中的值是最新的。因此,即使使用volatile还是会存在并发情况。
    比如:

    1. volatile static int a=0;
      线程A和线程B同时执行
    2. a++;

    此时线程A拿到a的最新值0,线程B也拿到最新值0;但是,A执行a++后,值为1,B也同样计算得到a=1,它们再同时写回到堆内存,使得最后a的值为1,并不为2.

    模拟代码如下:

    public class Demo {
        public volatile static int count =0;
        @org.junit.Test
        public void Test(){
            for (int i = 0; i < 1000; i++) {//创建1000个线程执行
                new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        
                        doCount();
                        
                    }
                }).start();
            }
            System.out.println(Demo.count);
        }
        
        
        public void doCount(){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
        }
    }
    

    结果会在0~1000之内摇摆不定,原因不用多说。所以,volatile不能保证数据的安全性,只能保证线程从堆中读取的是最新数据而已。

    参考地址:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html

    相关文章

      网友评论

          本文标题:Volatile理解

          本文链接:https://www.haomeiwen.com/subject/bdqtoxtx.html