我有一個多線程的應用程序,其中n個線程寫入ConcurrentHashMap
。另有n個線程從該映射中讀取並將其值複製到副本列表中。 之後,原始列表將從地圖中移除。 由於某種原因,我總是得到ConcurrentModificationException
。ConcurrentHashMap競賽條件問題
我甚至試圖用volatile布爾創建我自己的鎖定機制,但它不起作用。當使用Google Guava與Lists.newLinkedList()
我得到ConcurrentModificationException
。當使用StandardWay new LinkedList(list)
時,我得到一個ArrayOutOfBoundsException
。
以下是編譯的代碼示例:
public class VolatileTest {
public static Map<String, List<String>> logMessages = new ConcurrentHashMap<String, List<String>>();
public static AtomicBoolean lock = new AtomicBoolean(false);
public static void main(String[] args) {
new Thread() {
public void run() {
while (true) {
try {
if (!VolatileTest.lock.get()) {
VolatileTest.lock.set(true);
List<String> list = VolatileTest.logMessages.get("test");
if (list != null) {
List<String> copyList = Collections.synchronizedList(list);
for (String string : copyList) {
System.out.println(string);
}
VolatileTest.logMessages.remove("test");
}
VolatileTest.lock.set(false);
}
} catch (ConcurrentModificationException ex) {
ex.printStackTrace();
System.exit(1);
}
}
};
}.start();
new Thread() {
@Override
public void run() {
while (true) {
if (!VolatileTest.lock.get()) {
VolatileTest.lock.set(true);
List<String> list = VolatileTest.logMessages.get("test");
if (list == null) {
list = Collections.synchronizedList(new LinkedList<String>());
}
list.add("TestError");
VolatileTest.logMessages.put("test", list);
VolatileTest.lock.set(false);
}
}
}
}.start();
}
爲什麼我有任何問題,因爲我鎖定了完整的寫入/讀取操作? (當前用於測試目的) – 2015-03-03 10:35:59
您的鎖定模式不起作用,您需要對布爾值進行原子「檢查並設置」操作(請參閱AtomicBoolean)。或者一個鎖,它可以達到同樣的目的。 – GPI 2015-03-03 10:39:44
看到我編輯了我的答案。 – SMA 2015-03-03 10:39:47