java - 如何避免数据竞争——两个例子

标签 java parallel-processing atomic race-condition

我被告知以下代码示例存在数据竞争条件(当然假设是多线程):

class C { 
 private int x = 0; 
 private int y = 0; 

 void f() { 
     x = 1; 
     y = 1; 
 } 

 void g() { 
     int a = y; 
     int b = x; 
     assert(b >= a); 
 } 
} 

然而,我被告知以下“修复”没有数据竞争:

class C { 
 private int x = 0; 
 private int y = 0; 

 void f() { 
     synchronized(this) { x = 1; } 
     synchronized(this) { y = 1; } 
 } 

 void g() { 
     int a, b; 
     synchronized(this) { a = y; } 
     synchronized(this) { b = x; } 
     assert(b >= a); 
 } 
}

可以理解,上面的例子还有其他问题,但我只想知道为什么第二个代码块没有竞争条件。同步每个赋值语句如何消除数据竞争条件?一次只同步一个赋值语句有什么意义?

澄清一下,数据竞争是这样定义的:

数据竞争:同时读/写或同时写/写 内存位置

最佳答案

在第一个示例中,data 竞争条件将通过断言失败而被注意到。

这怎么可能呢? y > x 应始终为假,如 y写在x之后并在 x 之前阅读。

即使你考虑所有的交错

            Thread 1                 Thread 2
            ----------------------------------
            read y
            read x
                                     write x 1
                                     write y 1

你应该总是有x <= y

但在安全执行中,如果read v在执行 write v 期间, 无法保证读取的值

v is 0
T1 write 1:   wwwwwwwww
T2 read   :         rrrrr 
T3 read   :               rrrrr

在这种情况下,T2 读取的值可以是任何值,例如 42 .同时保证T3读到的值是1。

第一种情况ab可以是任何东西,所以断言可能会失败。 “修复”保证永远不会发生数据竞争(并发读\写),并且 ab将始终为 0 或 1。

关于java - 如何避免数据竞争——两个例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20677301/

相关文章:

java - OSGi 应用程序如何在 Java 9 上运行?

php - 如何编写异步 PHP 代码

c - 多进程无锁

python - Python 中的多处理 : Numpy + Vector Summation -> Huge Slowdown

c++ - 不要真正理解 std::atomic::compare_exchange_weak 和 compare_exchange_strong 的逻辑

c++11 atomic<int>++ 比 std::mutex protected int++ 慢得多,为什么?

c++ - 锁定自由链表插入

java - 无法解析符号 'DaggerAppComponent'

java - Java中的温度转换代码无法运行?

java - 如何在java上对某些文本进行编号?