在回答Does a correctly synchronized program still allow data race?(Part I)时,它给了我们一个很好的例子:程序的所有执行似乎都是顺序一致的,但它仍然存在数据竞争。它告诉我们为什么JLS中关于结论的另一个方向不正确:
如果某个程序没有数据争用,那么程序的所有执行都会显示为顺序一致。
现在看一下JLS中的另一个结论:
当且仅当所有顺序一致的执行都没有数据争用时,程序才能正确同步。
根据这个结论,上面的例子没有正确同步,所以正确的程序可能会被错误地同步吗?
答案 0 :(得分:2)
您可能需要首先定义正确的程序(不容易)。 JCiP提出(在不同的背景下):
如果程序符合其规格,则该程序是正确的。
使用该定义,提供的示例是正确的。但是,它没有正确同步(hash
上有数据竞争)。
==>正如该示例所证明的那样,正确的程序可能会被错误地同步。
答案 1 :(得分:1)
虽然这似乎没有回答OP的问题,但我会保留它以供评论。
您可以使用同步集合获得许多竞争条件。 e.g。
Vector<Integer> vector = ...
vector.add(1);
vector.set(0, 1 + vector.get(0));
每个方法都是同步的,但存在竞争条件。这是因为你可以让线程T1和T2完成。
T1: int tmp1 = vector.get(0);
T2: int tmp2 = vector.get(0);
T1: vector.set(0, 1 + tmp1);
T2: vector.set(0, 1 + tmp2);
在这种情况下,tmp1 == tmp2通常不是这种情况。
要正确同步,您可以执行以下操作以确保始终保持锁定。
synchronized(vector) {
vector.set(0, 1 + vector.get(0));
}