java之voliate

1、voliate特性

线程安全的三大特性:原子性,可见性,有序性,但是voliate只是具备可见性和有序性,不具备原子性。

2、voliate原理

2.1 可见性

为什么会有可见性?一般来说我如果共享的数据,每个线程修改后,另一个线程难道不能直接响应此共享数据吗?我们来验证一下这样的思想。下面stop是共享的数据,当stop没有添加voliate字段时,结果如下,线程A一致死循环中响应不到stop的修改。这是为什么?

Thread[main,5,main] after 1 seconds

加了voliate之后的结果是,线程A能响应到stop的修改了,这又是为什么?

Thread[main,5,main] after 1 seconds
Thread[Thread A,5,main] stopped 

public class VoliateTest {
    private  static boolean stop = false;

    public static void main(String[] args) {
        // Thread-A
        new Thread("Thread A") {
            @Override
            public void run() {
                while (!stop) {

                }
                System.out.println(Thread.currentThread() + " stopped");
            }
        }.start();

        // Thread-main
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread() + " after 1 seconds");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        stop = true;
    }
}

这是由于计算机内部有一个主内存,每一个线程都有自己的工作内存,对于共享数据,线程在修改时,会先从主内存中获取一份到自己的工作内存中,当修改后会将数据刷新到主内存中,另一个线程访问时,也是先从主内存获取,此时就会存在并发安全问题,如下图所示,当data被修改2后,在同步到主内存过程中,另一个线程查询data的值,此时data的值还是为1,此时存在的就是可见性问题了,其他线程不能感知到这个修改后的值。那加了voliate之后,底层又是怎么保证可见性的呢?

java之voliate_第1张图片

如下图所示,一般情况下,cpu不会直接和主内存通信,为了提高访问效率,会先将数据读到高速缓存中,当某个cpu对数据进行修改后,不知道何时会回写到主内存中。如果添加了voliate,当数据被修改后,JVM会向CPU发送一条LOCK的前缀的指令,此时会将修改后的数据从缓存中同步到主内存中,主内存中的数据被修改后,每个CPU的缓存数据和主内存还不一致怎么办?

为了达到数据一致性,每个cpu都访问高速缓存时,需要遵循缓存一致性协议。即每个CPU都会嗅探总线中传播的数据来检查自己缓存中的数据是否过期,当发现缓存行对应的主内存的地址被修改后,则会将缓存行数据置为无效状态,当对缓存行的数据进行修改操作时,则会重新从主内存读取相应的数据到缓存中。

java之voliate_第2张图片

2.2 有序性

为了性能优化,JMM在不改变正确语义的条件下,允许编译器和处理器对指令序列进行重新排序,而内存屏障则会阻止这种重排序。

当指令间插入一个内存屏障时,能保证指令前或后的指令有序执行。当然内存屏障也分为读屏障和写屏障。

读屏障:

插入读屏障之后,高速缓存中的行数据会失效,强制从主内存重新读取数据

写屏障:

插入写屏障之后,保证高速缓存中的数据在修改后写入到主内存中

可见上述读屏障和写屏障也保证了可见性。

2.3 原子性

voliate不具有原子性的,最简单的例子就是i++操作,i为共享数据,当两个线程同时对i做i++操作时,由于i++操作不是一个操作,是两个操作,即读取i和对i进行累加操作,当两个线程都将i读取到高速缓存后,对i进行累加操作,最后主内存的i仅仅只做了一次累加操作。说明不具有原子性。

总结:

voliate只有可见性、有序性,不具备原子性。可见性使用的缓存一致性功能和内存屏障保证的。有序性是靠内存屏障保证的。

 

你可能感兴趣的:(java,java,开发语言)