美文网首页
volatile语义

volatile语义

作者: sunpy | 来源:发表于2018-10-09 10:06 被阅读9次

    介绍

    我们经常看到volatile(易变的)修饰的变量,这个volatile是jvm提供的一种轻量级的同步手段,但是对于它自身使用场景,优缺点经常都是从每个片面的点去理解的,没有形成体系,打算总结下形式记忆体系。

    volatile的特性

    1. 可见性
      就是保证变量对于所有线程都是可见的。对于volatile修饰的变量的读总能看到最后对该变量的写。
    2. 原子性
      就是保证任意单个volatile变量的读写操作具有原子性(但是volatile++这种复合操作不具备原子性)。
    public class VolatileTest {
    
        public static volatile int i = 0;
        
        public static void iinc() {
            i++;
        }
        
        public static void main(String[] args) {    
            for (int t = 0 ; t < 30 ; t++) {
                new Thread(new Runnable() {
    
                    public void run() {
                        for (int j = 0 ; j < 1000 ; j++) {
                            iinc();
                        }
                    }
                }).start();
            }
            
            while (Thread.activeCount() > 1) {
                Thread.yield();
            }
            
            System.out.println(i);
        }
    }
    
    1.jpg

    说明:应对这个情况我们想要原子性的int值可以采用AtomicInteger类来解决问题。

    happens-before中的volatile

    之前java内存模型讲到,java内存模型会使用重排序来优化程序,单线程的情况下,虽然数据有依赖性,但是在单线程中java内存模型会遵守as-if-serial语义来保证结果不会因为重排序改变。但是在多线程下就无法保证指令重排序了;但是volatile变量是禁止指令重排序优化的。happens-before性质定义了规则:对于volatile变量得写操作happens-before读操作

    volatile内存语义

    当写一个volatile变量时,java内存模型会把该线程对应的本地内存中的共享变量值刷新到主内存;store+write操作。
    当读一个volatile变量时,java内存模型会把该线程对应的本地内存设置为无效,然后线程从主内存读取共享变量;read+load操作。

    相关文章

      网友评论

          本文标题:volatile语义

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