java linkedlist返回相同的元素多线程

时间:2015-03-30 19:38:27

标签: java multithreading linked-list thread-safety synchronized

我想将我的 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次。

如何使其线程安全?

2 个答案:

答案 0 :(得分:1)

代码必须在相同的对象上同步。

如果这样做 - 并且程序的其余部分正确,并且这是LinkedList被访问的唯一位置 - 那么它将按预期工作,有或没有线程。如果使用相同的对象,则同步块不够大,并且发布的代码不会显示问题。

FWIW:请参阅Matt的答案,了解一些替代线程安全设计数据结构。但请注意,如果问题没有使用相同的同步对象,这些将解决问题。

答案 1 :(得分:0)

不要将普通LinkedList用于并发目的:

  

请注意,此实现未同步。如果多个线程同时访问链接列表,并且至少有一个线程在结构上修改了列表,则必须同步外部

至少使用the LinkedList JavaDocs中描述的Collections.synchronizedList()

更好:使用线程安全的并发数据结构,例如ConcurrentLinkedQueueArrayBlockingQueueLinkedBlockingQueue