3

在回答正确同步的程序是否仍然允许数据竞争?(第一部分)时,它给了我们一个很好的例子:一个程序的所有执行似乎都是顺序一致的,但它仍然存在数据竞争。它告诉我们为什么JLS中以下结论的另一个方向是不正确的:

如果一个程序没有数据竞争,那么程序的所有执行都将看起来是顺序一致的。

现在看看JLS中的另一个结论:

当且仅当所有顺序一致的执行都没有数据竞争时,程序才能正确同步。

根据这个结论,上面的例子没有正确同步,那么一个正确的程序会不会被错误地同步呢?

4

2 回答 2

2

您可能需要首先定义什么是正确的程序(不容易)。JCiP 建议(在不同的背景下):

如果一个程序符合它的规范,它就是正确的。

使用该定义,提供的示例是正确的。但是,它没有正确同步(在 上存在数据竞争hash)。

==> 如该示例所证明的,正确的程序可能会错误地同步。

于 2012-08-22T12:37:40.650 回答
1

虽然这似乎没有回答 OP 的问题,但我保留它以供评论。


您可以使用同步集合获得许多竞争条件。例如

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));
}
于 2012-08-22T12:37:32.180 回答