Multithreading 具有两个线程的良性数据竞争条件
这是比赛条件吗Multithreading 具有两个线程的良性数据竞争条件,multithreading,race-condition,Multithreading,Race Condition,这是比赛条件吗 class A { int x; update() { x = 5; } retrieve() { y = x; } } 如果update()和retrieve()由两个不同的线程调用,并且没有持有任何锁,那么假设共享变量的两次访问中至少有一次写入,那么这可以归类为竞争条件。但这真的是运行时的问题吗 没有锁,可能会发生三件事: y获取x(5)的新值 y获取x的旧值(很可能是0) 如果写入int的内容不是原子的,则y
class A {
int x;
update() {
x = 5;
}
retrieve() {
y = x;
}
}
如果update()和retrieve()由两个不同的线程调用,并且没有持有任何锁,那么假设共享变量的两次访问中至少有一次写入,那么这可以归类为竞争条件。但这真的是运行时的问题吗 没有锁,可能会发生三件事:
y
获取x
(5)的新值y
获取x
的旧值(很可能是0)int
的内容不是原子的,则y
可以获取任何其他值int
的读取是原子的,因此第三个选项不能出现。不能保证其他语言中的原子性
通过锁定,前两个选项也可以发生
不过,根据内存模型,还有一个额外的挑战。在Java中,如果一个写操作没有同步,它可以被任意延迟到下一个同步点(一个synchronized
块的末尾或一个volatile
字段的访问)。类似地,可以从上一个同步点(同步的块的开始或对volatile
字段的访问)任意缓存读取。这很容易导致过时缓存引起的问题。最终的结果是,第二种选择可能发生,即使第一种选择应该发生
在Java中,始终对可以从其他线程访问的字段使用volatile
,否则您将面临由于内存访问重新排序而导致的难以调试的争用条件。同样的警告也适用于使用类似于Java的内存模型的其他语言-您可能需要告诉编译器不要进行这些优化。什么语言?或者说这是一个语言不可知的问题吗?把这样一个粗俗的种族称为“良性”就像在C++中调用一只老虎一样大,不稳定不保证任何同步或记忆障碍。它所做的只是防止某些类型的优化。我听说VC++会无缘无故地创建一个内存屏障,但这不是标准的。@JiveDadson那么它就不是Java的volatile
的等价物了。重写。@JiveDadson如果volatile
关键字没有剪切它,那么我不知道会发生什么。Microsoft编译器可以保证这一点: