我想将我的 PacketHandler 读取的 数据包 添加到LinkedList
中
用以下方法保存:
Packet toAdd = handler.handlePacket(socket.getInputStream());
synchronized (packetsRead) {
packetsRead.addLast(toAdd);
if (debug) {
System.out.println(packetsRead.getLast().toString());
}
}
并用
阅读synchronized (packetsRead) {
if (packetsRead.size() > 0) {
return packetsRead.pollFirst();
}
}
用第一种方法中的调试方法我可以看到 最后一项永远不变。所以不同的数据包被添加到我的列表中。
但是当我尝试从不同的线程中读取它们时,我总是得到相同的数据包。
例如,如果我的列表中有10个不同的数据包,它将返回第一个10次。
如何使其线程安全?
答案 0 :(得分:1)
代码必须在相同的对象上同步。
如果这样做 - 并且程序的其余部分正确,并且这是LinkedList
被访问的唯一位置 - 那么它将按预期工作,有或没有线程。如果使用相同的对象,则同步块不够大,并且发布的代码不会显示问题。
FWIW:请参阅Matt的答案,了解一些替代线程安全设计数据结构。但请注意,如果问题没有使用相同的同步对象,这些仅将解决问题。
答案 1 :(得分:0)
不要将普通LinkedList
用于并发目的:
请注意,此实现未同步。如果多个线程同时访问链接列表,并且至少有一个线程在结构上修改了列表,则必须同步外部
至少使用the LinkedList
JavaDocs中描述的Collections.synchronizedList()
。
更好:使用线程安全的并发数据结构,例如ConcurrentLinkedQueue
,ArrayBlockingQueue
或LinkedBlockingQueue
。