tem*_*per 22 java synchronization volatile
这是关于不稳定的背驮式.目的:我希望达到轻量级vars visibilty.a_b_c的一致性并不重要.我有一堆vars,我不想让它们都变得不稳定.
这段代码是否安全?
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}
Run Code Online (Sandbox Code Playgroud)
Ada*_*man 33
Java Memory Model定义了before-before关系,它具有以下属性(以及其他属性):
这两个属性以及先发生关系的传递性意味着可见性保证OP以下列方式寻求:
a螺纹1 之前发生一个写sync在调用sync()在线程1(程序顺序规则).sync在调用sync()在线程1 之前发生的读出,以sync在呼叫到sync在螺纹2(易失性可变规则).sync在调用sync()中的线程2 之前发生的读取距离a在2线(程序顺序规则).这意味着,这个问题的答案是肯定的,即呼吁sync()在线程1每次迭代和2,确保变更的可视性a,b并且c给其他线程(或多个).请注意,这仅确保可见性.不存在互斥保证,因此所有不变量都具有约束力a,b并且c可能会受到违反.
另请参阅Java理论与实践:修复Java内存模型,第2部分.特别是"挥发性新保证"一节
在新的内存模型下,当线程A写入易失性变量V,并且线程B从V读取时,在写入V时对A可见的任何变量值现在都保证对B可见.
使用just绝对不能在线程之间增加值volatile。这只能确保每个线程获取最新值,而不是确保增量是原子的,因为在汇编器级别,++实际上是可以交错的几条指令。
您应该使用AtomicInteger快速原子增量。
编辑:再次阅读所需的内容实际上是一个内存围栏。Java没有内存围栏指令,但是您可以对内存围栏“副作用”使用锁定。在这种情况下,请声明sync方法同步以引入隐式篱笆:
void synchronized sync() {
sync++;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5474 次 |
| 最近记录: |