文档章节

【翻译十】volatile的含义

Geeyu
 Geeyu
发布于 2017/03/26 00:35
字数 1287
阅读 11
收藏 0

volatile的两层语义

  • 保证共享变量的可见性

  • 禁止进行指令重排序

What does volatile do?

Volatile fields are special fields which are used for communicating state between threads. Each read of a volatile will see the last write to that volatile by any thread; in effect, they are designated by the programmer as fields for which it is never acceptable to see a "stale" value as a result of caching or reordering. The compiler and runtime are prohibited from allocating them in registers. They must also ensure that after they are written, they are flushed out of the cache to main memory, so they can immediately become visible to other threads. Similarly, before a volatile field is read, the cache must be invalidated so that the value in main memory, not the local processor cache, is the one seen. There are also additional restrictions on reordering accesses to volatile variables.

Volatile字段是用来线程间交流状态的特殊字段。线程对volatile的每次读,都会看到其他线程对它的最后一次写,也就是说,volatile是随时最新的。实际上,volatile被设计为,在缓存或重排序中从不会失效的。JMM不允许编译器和运行时将volatile字段分配到寄存器中,只能在写入后,刷进主内存中,因此volatile字段的值总是对其他字段可见的。相似的,在读取前,会先清空本地处理器缓存,因此就可以看到主内存中的最新值了。此外,JMM对volatile变量的访问重排序也有限制。

Under the old memory model, accesses to volatile variables could not be reordered with each other, but they could be reordered with nonvolatile variable accesses. This undermined the usefulness of volatile fields as a means of signaling conditions from one thread to another.

在旧的内存模型下,对volatile变量的访问,不能被重排序,但访问非volatile变量却可以重排序。这破坏了volatile在多线程中作为一个状态信号的作用。

Under the new memory model, it is still true that volatile variables cannot be reordered with each other. The difference is that it is now no longer so easy to reorder normal field accesses around them. Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.

在新内存模型下,volatile变量同样不能被重排序,区别在于,volatile变量周围的普通字段也不会被轻易重排序。在内存的效果上,写volatile与释放监视器相同,读volatile与获取监视器相同。事实上,当对volatile及其他字段的访问在一起的时候,由于新内存模型更加严格的重排序约束,不管变量f是否volatile,当A线程写f时,对于任何对其可见的变量,另一条正在读f的线程也能看到。

这部分翻译很蛋疼,完全不知道原文什么意思,但是看过参考文章后,就立马明白了。对volatile变量访问的语句,前(后)面的不能重排序到后(前)面,但是前(后)面的还是可以重排序的。

Here is a simple example of how volatile fields can be used:

以下是volatile字段的用法:

    class VolatileExample {
      int x = 0;
      volatile boolean v = false;
      public void writer() {
        x = 42;
        v = true;
      }
    
      public void reader() {
        if (v == true) {
          //uses x - guaranteed to see 42.
        }
      }
    }

Assume that one thread is calling writer, and another is calling reader. The write to v in writer releases the write to x to memory, and the read of v acquires that value from memory. Thus, if the reader sees the value true for v, it is also guaranteed to see the write to 42 that happened before it. This would not have been true under the old memory model. If v were not volatile, then the compiler could reorder the writes in writer, and reader's read of x might see 0.

假设一条线程调用writer,另一条调用reader。writer中v的写入会将x的写入发布到内存中,而reader中v的读取,会从内存中获取x。因此,当reader看到v是true的时候,肯定也会看到在v之前赋值的x,且x已经是42了。如果v不是volatile,那么writer中可能重排序,读到的x就有可能为0.

Effectively, the semantics of volatile have been strengthened substantially, almost to the level of synchronization. Each read or write of a volatile field acts like "half" a synchronization, for purposes of visibility.

实际上,volatile的语义被加强了,几乎达到了同步的水平。为了可见性,每个volatile的写入都相当于半个同步。

Important Note: Note that it is important for both threads to access the same volatile variable in order to properly set up the happens-before relationship. It is not the case that everything visible to thread A when it writes volatile field f becomes visible to thread B after it reads volatile field g. The release and acquire have to "match" (i.e., be performed on the same volatile field) to have the right semantics.

注意:为了设置合适的happens-before关系,每条线程都应该访问相同的volatile变量

参考文章

感觉翻译了半天还是挺晕的,没理解而且抱有疑问,于是又找到以下文章《深入理解volatile关键字》,作者思路清楚,文中所述相当于这一系列的翻译总结,且更加适合阅读。

© 著作权归作者所有

Geeyu
粉丝 3
博文 57
码字总数 30351
作品 0
昌平
私信 提问
volatile与synchronized使用比较

volatile英文含义【易变的】其实就是告诉CPU使用前必须重新去取值。 volatile比synchronized轻量级,不会造成阻塞,但是只实现了部分synchronized的功能。 volatile能保证可见性和有序性。但...

karma123
2018/08/31
18
0
C语言 —— const和volatile同时修饰某对象的意义

const和volatile同时修饰某对象的意义: volatile const int i; (1)本程序段中不能对 i 做修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心; (2)另一个程序段则...

follitude
2016/05/13
164
0
Effective C++: volatile

volatile和const一样是C++的类型修饰符(type specifier),即可以用来修饰变量,也可以用来修饰指针,甚至是用户自定义类型,函数等. 遇到这个变量的时候编译器对遇到该关键字的代码不再进行优...

SHIHUAMarryMe
2016/05/17
361
0
Redis单机系列文章--1.Redis单机的安装和配置(含视频)

转载请注明出处哈:http://carlosfu.iteye.com/blog/2240426 一、Redis单机下载、编译、安装: cd /opt/softwget http://download.redis.io/releases/redis-3.0.4.tar.gztar xzf redis-3.0.4......

付磊-起扬
2015/09/16
0
0
c语言面试题

面试题: (void *)ptr 和 (*(void**))ptr的结果是否相同?其中ptr为同一个指针 有人帮我分析下(*(void**))到底表达啥含义啊? 另外,下面的也是如此,不是很明白这种强制转换的用途和目的,请...

天王盖地虎626
2018/07/14
285
2

没有更多内容

加载失败,请刷新页面

加载更多

如何在Linux中复制文档

在办公室里复印文档过去需要专门的员工与机器。如今,复制是电脑用户无需多加思考的任务。在电脑里复制数据是如此微不足道的事,以致于你还没有意识到复制就发生了,例如当拖动文档到外部硬盘...

老孟的Linux私房菜
54分钟前
23
0
SpringBoot 集成MongoDB

一、MongoDB 简介 MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB,但对于大部分公司,使用 MongoDB 的场景是做大规模数据查询...

zw965
今天
32
0
使用 Envoy 和 AdGuard Home 阻挡烦人的广告

> 原文链接:使用 Envoy 和 AdGuard Home 阻挡烦人的广告 通常我们使用网络时,宽带运营商会为我们分配一个 DNS 服务器。这个 DNS 通常是最快的,距离最近的服务器,但会有很多问题,比如: ...

米开朗基杨
今天
35
0
springboot之全局处理异常封装

springboot之全局处理异常封装 简介 在项目中经常出现系统异常的情况,比如NullPointerException等等。如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系...

Purgeyao
今天
42
0
cookie

cookie: n. 饼干;小甜点 为什么会引入Cookie(在客户端保持http状态) 因为http协议是一种无状态协议,web服务器本身不能识别出哪些请求是同一个服务器发送的,浏览器的每一次请求都是独立...

五公里
今天
41
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部