2011-10-22 93 views
2

之間的訪問,我不能夠同步使用一組兩個線程:一個synchronizedSet同步兩個線程

private Set<String> set; 
... 
set = Collections.synchronizedSet(new HashSet<String>()); 

並將它傳遞給兩個線程。一個存取:

synchronized (set) { 
    // [1] 
    if (set.contains(str)) { 
    ... 
    } else { 
     // [3] 
    } 
} 

和另一個更新:

synchronized (set) { 
    set.add(str); // [2] 
... 
} 

什麼情況是,[1],[2],[3]發生在序列。在[1]期間,該集合還沒有我正在尋找的項目是正確的。但是[2]通過添加項目來更新它。在[3]期間,我現在看到了這個項目。我該如何解決?我也有一個ConcurrentHashMap被相同的線程共享,但它工作得很好。該套件等同於ConcurrentHashMAp?

更新:代碼太長。無論如何,我更新的問題是 - 什麼是該集相當於ConcurrentHAshMap?

+0

1-> 2-> 3不應該發生。 1-> 3與2互斥。也就是說,當調用1時,直到調用3之後纔會調用2(如果調用3)。 –

+0

提供plz完整代碼片段。這些同步塊不允許同時運行兩個或多個線程,既不設置同步也不設置線程安全。 – svaor

+0

爲了進行調試,使用http://download.oracle.com/javase/6/docs/api/java/lang/System.html#identityHashCode(java.lang.Object)打印出每個線程中該集的標識。檢查它們是否都使用相同的同步包裝... –

回答

5

您正在同步訪問正確。實際上,在synchronizedSet()中包裝它在這裏沒有任何附加效果。沒有ConcurrentHashSet,雖然你可以從Collections.newSetFromMap()ConcurrentHashMap得到相同的東西。但這不是問題。

問題是在你的代碼中的其他地方。例如:你確定你在同一組中同步嗎?你的密鑰是否正確實施hashCode()equals()?你是否讓它們變得可變(壞主意),並且改變了鍵?