挥发性背驮式。这对于visiblity来说足够了吗? [英] Volatile piggyback. Is this enough for 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:
- 写入
a 线程1中的code> 在
sync()的调用
中写入sync
之前发生线程1中的code>(程序订单规则)。 - 在<$ c $的调用中写入
sync
c>在线程1中的sync() 发生在之前在线程2(易变变量规则)中对sync
的调用中读取sync
。 - 在线程2 中对
sync()
的调用中读取sync
在从线程2中读取a
之前(程序订单规则)。
- A write to
a
in thread 1 happens-before a write tosync
in a call tosync()
in thread 1 (program order rule). - The write to
sync
in the call tosync()
in thread 1 happens-before a read tosync
in a call tosync
in thread 2 (volatile variable rule). - The read from
sync
in the call tosync()
in thread 2 happens-before a read froma
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屋!