【发布时间】:2013-10-13 14:09:55
【问题描述】:
这是我的课程,有两种方法修改列表PacketQueue。这两个方法在两个线程中执行,所以标记了synchronize。
public class MessageHandler implements nuctrl.interfaces.MessageHandler, Runnable {
private static final List<GatewayMsg> PacketQueue = new LinkedList<GatewayMsg>();
@Override
public void insert(GatewayMsg msg) {
synchronized (PacketQueue){
PacketQueue.add(msg);
PacketQueue.notify();
}
log.debug("insert " + msg.toString());
}
@Override
public void run() {
while(running){
synchronized (PacketQueue){
try {
while(PacketQueue.size() == 0){
PacketQueue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
for (GatewayMsg msg : PacketQueue){
PacketQueue.remove(msg);
packetHandler.onPacket(msg);//method call
}
}
}
}
}
run() 用于 thread-4,insert() 用于另一个线程(I/O Worker #1)。 Synchronized 已添加,一切正常,但我仍然不断收到 ConcurrentModificationException。
DEBUG [New I/O worker #1] (MessageHandler.java:47)| insert GatewayMsg<>
Exception in thread "Thread-4" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at nuctrl.core.MessageHandler.run(MessageHandler.java:67)
at java.lang.Thread.run(Thread.java:680)
这让我快疯了!任何人都可以帮助找出错误吗?或者其他方式来做同样的事情?
【问题讨论】:
-
每次更改后显示列表条目的解决方案和逻辑不是很酷,那么
insert()方法中插入后的内容为什么不显示呢?!当列表中有一个(或多个)对象时,它可能会出现错误,因此run()将永远锁定并显示该条目。 -
看来您正在尝试解决“生产者-消费者问题”。如果是这样,您可能想查看 java 中的 BlockingQueue,它可以帮助您巧妙地做到这一点。
标签: java multithreading race-condition synchronized