我有一个多线程的应用程序,其中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