挥发性背驮式。这对于visiblity来说足够了吗? [英] Volatile piggyback. Is this enough for visiblity?

查看:134
本文介绍了挥发性背驮式。这对于visiblity来说足够了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是关于不稳定的背驮式。
目的:我希望达到轻量级vars visibilty。 a_b_c的一致性并不重要。我有一堆变量,我不想让它们全部变化。

This is about volatile piggyback. Purpose: I want to reach a lightweight vars visibilty. Consistency of a_b_c is not important. I have a bunch of vars and I don't want to make them all volatile.

这个代码线程是否安全?

Is this code threadsafe?

class A {
    public int a, b, c;
    volatile int sync;

    public void setup() {
        a = 2;
        b = 3;
        c = 4;
    }

    public void sync() {
        sync++;
    }
}

final static A aaa = new A();

Thread0:
aaa.setup();
end

Thread1:
for(;;) {aaa.sync(); logic with aaa.a, aaa.b, aaa.c}

Thread2:
for(;;) {aaa.sync(); logic with aaa.a, aaa.b, aaa.c}


推荐答案

Java内存模型定义发生在之前关系,该关系具有以下属性(以及其他):

Java Memory Model defines the happens-before relationship which has the following properties (amongst others):


  • 线程中的每个动作都发生在 - 在程序顺序中稍后出现的该线程中的每个动作之前(程序顺序规则)

  • 在每个动作之前发生对易失性字段的写入随后读取相同的易失性(易变量规则)

这两个属性与的传递性发生在之前关系意味着可见性保证OP以下列方式寻求:

These two properties together with transitivity of the happens-before relationship imply the visibility guarantees that OP seeks in the following manner:


  1. 写入 a sync()的调用中写入 sync 之前发生(程序订单规则)。

  2. 在<$ c $的调用中写入 sync c>在线程1中的sync() 发生在之前在线程2(易变变量规则)中对 sync 的调用中读取 sync

  3. 在线程2 中对 sync()的调用中读取 sync 从线程2中读取 a 之前(程序订单规则)。

  1. A write to a in thread 1 happens-before a write to sync in a call to sync() in thread 1 (program order rule).
  2. The write to sync in the call to sync() in thread 1 happens-before a read to sync in a call to sync in thread 2 (volatile variable rule).
  3. The read from sync in the call to sync() in thread 2 happens-before a read from a in thread 2 (program order rule).

这意味着问题的答案是肯定的,即在线程1和2的每次迭代中调用 sync()可确保对<$的更改的可见性c $ c> a b c 到其他线程。请注意,这只能确保可见性。不存在互斥保证,因此所有不变量绑定 a b c 可能会被违反。

This implies that the answer to the question is yes, i.e. the call to sync() in each iteration in threads 1 and 2 ensures visibility of changes to a, b and c to the other thread(s). Note that this ensures visibility only. No mutual exclusion guarantees exist and hence all invariants binding a, b and c may be violated.

另请参阅 Java理论与实践:修复Java内存模型,第2部分。特别是新的易失性保证部分,其中

See also Java theory and practice: Fixing the Java Memory Model, Part 2. In particular the section "New guarantees for volatile" which says


在新的内存模型下,当线程A写入易变的$ b $时b变量V,线程B从V读取,在写入V时A可见的
的任何变量值现在保证为B可见的

Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B.

这篇关于挥发性背驮式。这对于visiblity来说足够了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆