最终变量和lazySet实现都需要LoadStore和StoreStore吗?

时间:2014-09-22 12:31:25

标签: java performance concurrency compiler-optimization volatile

我正在阅读Hans的一篇文章,他认为在lazySet或最终变量写入之前也需要LoadStore。

他表现出一种我无法理解的特定种族状况。

http://www.hboehm.info/c++mm/no_write_fences.html 参见 收件人写入对象

非常违反直觉,x.a = 43的线程1存储可以通过StoreStore屏障完成,因为它完全违背了StoreStore Barrier的目的。

此处类似论点http://shipilev.net/blog/2014/all-fields-are-final/

在这里复制Shiplev:

" JSR 133 Cookbook只需要StoreStore,但也可能需要LoadStore障碍。当最终字段从其他一些经历了更新的字段初始化时,这涵盖了一个极端情况。 这个角落案例可以通过运行时优化来启用,这表明最终的商店不是需要,将值放在局部变量中,因此单独停止StoreStore的排序保证"

*运行时如何计算出最终存储不是必需的,如果负载正在通过/重新排序StoreStore Barrier然后存储到本地变量也正在通过storeStore屏障传递/重新排序,这是我要做的部分&#39 ; t很明白,为什么存储到本地变量可以使用StoreStore Barrier重新排序。如何/何时运行时可以确定存储到本地变量就足够了*

如果有人能够通过一些简单的例子更详细地解释他们都提到的竞争条件,那将会非常有帮助。

1 个答案:

答案 0 :(得分:4)

我的帖子引用令人困惑和过时,我很久以前就修好了;对困惑感到抱歉。欢迎您在下次发送邮件时给我发邮件。真的,它遵循Hans Boehm's example,这很简单:

x.a = 0; x.a++;
x_init.store_write_release(true);
     

并且在线程2中使用x的代码更新它,例如

if (x_init.load_acquire())
    x.a = 42;
     

如果线程1中的发布存储仅限于确保   先前存储(写入)的完成,线程1中的x.a的加载(部分   x.a ++)可以通过赋值x_init有效地重新排序,   因此可以看到值为42,导致x.a被初始化为   43。