美文网首页
Volatile的内存语义

Volatile的内存语义

作者: WillReading | 来源:发表于2018-07-30 23:39 被阅读0次

    内存语义

    内存语义指的是:
    在多线程或处理器中用来控制存取共享内存位置,或者说是在更高层次上共享变量的处理逻辑。

    volatile的happens-before原则

    volatile变量原则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。

    volatile的内存语义

    volatile的内存语义即是用来保证volatile的happens-before原则。

    • volatile写:当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。


    • volatile读:当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。


    • 线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所做修改的)消息。

    • 线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。

    • 线程A写一个 volatile变量,随后线程B读取这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。

    volatile内存语义的实现

    为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

    内存屏障是一种barrier指令类型,它导致CPU或编译器对barrier指令前后发出的内存操作执行顺序约束。也就是说,在barrier之前的内存操作保证在barrier之后的内存操作之前执行。

    内存屏障有以下4种:

    • LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
    • StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
    • LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
    • StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。 在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。

    为了实现volatile内存语义,Java编译器会这样使用内存屏障:


    内存屏障 ---实现---> 内存语义 ---保证---> happens-before原则

    参考资料

    相关文章

      网友评论

          本文标题:Volatile的内存语义

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