美文网首页
volatile修饰符

volatile修饰符

作者: 叫我胖虎大人 | 来源:发表于2019-08-15 10:34 被阅读0次

    在多线程并发编程当中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。


    CPU的术语定义

    volatile保证可见性

    Java代码如下
    instance = new Singleton(); // instance是volatile变量

    转变成汇编代码,如下。

    0x01a3de1d: movb 0×0,0×1104800(%esi);0x01a3de24: lock addl0×0,(%esp);

    有volatile变量修饰的共享变量进行写操作的时候会多出第二行汇编代码,Lock前缀的指令在多核处理器下引发了两件事情.

    • 1)将当前处理器缓存行(Cache Line)写回系统内存(也就是主内存).
    • 2)这个写回内存操作将会使得其他CPU里缓存了该内存地址的数据无效

    volatile的两条实现原则

    • 1)Lock前缀指令会引起处理器缓存回写到内存。
    • 2)一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

    volatile的实现机制

    通过内存屏障和禁止重排序优化来实现

    • 对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量刷新到主内存


    • 对volatile变量读操作时,会在读操作钱加入一条load屏障命令,从主内存中读取共享变量



    volatile的应用场景

    volatile不具有原子性,所以不适合用于计数等场景
    volatile的使用具有条件

    • 1.对变量的写操作不依赖当前值
    • 2.该变量不包含于其他变量的不变式当中

    适合作为标记量,双重检测
    eg:

    volatile boolean inited = false;
    //thread 1
    context = loadContext();
    inited = false;
    
    //thread 2
    while(!inited){
        sleep();
    }
    doSomethingWithConfig(context);
    

    相关文章

      网友评论

          本文标题:volatile修饰符

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