2012-08-22 69 views
3

在回答Does a correctly synchronized program still allow data race?(Part I)時,它給了我們一個很好的例子:程序的所有執行看起來都是順序一致的,但它仍然有數據競爭。它告訴我們,爲什麼在JLS以下結論的另一個方向是不正確的:可能正確的程序不正確同步?

如果程序沒有數據競爭,那麼該程序的所有執行會顯得順序一致。

現在看看另一個conclucsion在JLS

的程序是否能正確同步,當且僅當所有順序一致的執行都是免費的數據競爭。

根據這個結論,上面的例子沒有正確同步,所以正確的程序可能會被錯誤地同步嗎?

+0

現** **這就是我所說的「很快」! –

回答

2

您可能需要首先定義一個正確的程序是什麼(不容易)。 JCiP建議(在不同的上下文中):

如果程序符合其規範,則該程序是正確的。

使用該定義,提供的示例是正確的。但是,它沒有正確同步(在hash上有數據競賽)。

==>正確的程序可能會被錯誤地同步,正如該例所證明的那樣。

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)); 
} 
+0

彼得,你沒有展示*數據競賽*的實例,這是OP詢問的。 OP真的專注於術語的確切用法,他在過去的幾天裏一直在閱讀和重讀JLS到最後一封信:) –

+0

@MarkoTopolnik好的,你能說出「競態條件」和「數據競賽「? –

+0

* *數據爭奪*只是一種非常狹窄的*爭用條件*,涉及非易失性變量的衝突線程間操作,這些非易失性變量並非由* happens-before *命令所排序。在您的代碼中,所有訪問都是有序的。 –