ConcurrentLinkedQueue 的内存一致性是如何保证的?

2020-07-25 10:41:12 +08:00
 amiwrong123

前提:jdk8

ConcurrentLinkedQueue 的注释中有这么一段话:

Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a ConcurrentLinkedQueue happen-before actions subsequent to the access or removal of that element from the ConcurrentLinkedQueue in another thread.

翻译过来就是:先发生的插入操作 happen-before 后发生的访问或移除操作。

看了下内存一致性的相关概念,还是有点云里雾里。总之,上面这句话,是通过 ConcurrentLinkedQueue 的代码实现(源码也看过了)来保证的吗?还是通过更底层的东西来保证的?

怎么做到保证的啊。

求大佬们帮忙解答

1873 次点击
所在节点    Java
6 条回复
xiongxin8802
2020-07-25 10:58:18 +08:00
先插入的操作,利用 happen-before 原则,保证多线程情况下的一致性,就是其他线程都能看到你插入的数据
falsemask
2020-07-25 11:01:18 +08:00
应该是通过用 volatile 修饰 Node 来实现的。Happens-before 原则:一个 volatile 变量的写操作发生在这个 volatile 变量随后的读操作之前。这意味着线程 a 在写入变量之前的操作对线程 b 读取变量时都可见。
secondwtq
2020-07-25 11:21:00 +08:00
JDK 没看过,但楼主这个翻译有问题,是对一个特定的元素,某一线程插入该元素之前(prior to)的操作 happen-before 其他线程访问或删除该元素之后(subsequent to)的操作。
amiwrong123
2020-07-25 12:03:43 +08:00
@secondwtq
看来我的英文水平有待提高,确实应该你这个意思。之前完全理解错了。。网络上各个博客关于这句话,居然还都是我这么翻译的。。
amiwrong123
2020-07-25 12:06:26 +08:00
@falsemask
node 的 next 指针是 volatile 的,要想入队,就得 CAS 修改 last node 的 next 指针。只有修改成功了,别的线程才能从队列出发找到这个新 node,才可能对它进行访问或删除。

所以重点在于 node 的 next 指针是 volatile 的呗
Jooooooooo
2020-07-25 13:19:02 +08:00
注意 happen-before 就行了

我理解你不太懂的是这个 happen-before 是怎么实现的, 搜一下 synchronize 的原理其它的就都懂了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/692972

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX