可以在多个线程中安全地读取Java LinkedList吗?

可以在多个线程中安全地读取Java LinkedList吗?,java,Java,我希望多个线程在LinkedList中的元素之间进行迭代。我不需要写入LinkedList。这样做安全吗?或者我需要一个同步的列表来让它工作吗 谢谢大家! 来自: 请注意,此实现是不同步的。如果多个线程同时访问一个链表,并且至少有一个线程在结构上修改链表,则必须在外部对其进行同步。(结构修改是添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这通常通过在自然封装列表的某个对象上进行同步来实现。如果不存在这样的对象,则应使用集合“包装”列表 换句话说,如果你真的只是迭代,那么你就没

我希望多个线程在LinkedList中的元素之间进行迭代。我不需要写入LinkedList。这样做安全吗?或者我需要一个同步的列表来让它工作吗

谢谢大家!

来自:

请注意,此实现是不同步的。如果多个线程同时访问一个链表,并且至少有一个线程在结构上修改链表,则必须在外部对其进行同步。(结构修改是添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这通常通过在自然封装列表的某个对象上进行同步来实现。如果不存在这样的对象,则应使用集合“包装”列表


换句话说,如果你真的只是迭代,那么你就没事了,小心点。

他们可以安全地这样做,前提是:

  • 它们在开始迭代之前与(所有)已写入列表的线程同步,并且
  • 迭代期间没有线程修改列表

第一点是必要的,因为除非在开始之前进行了适当的同步,否则一个“写入”线程可能对本地缓存或寄存器中的列表数据结构进行了未刷新的更改,或者一个读取线程在其缓存或寄存器中具有过时的列表状态

(这是需要对Java内存模型有深入了解才能知道场景是否真正是线程安全的情况之一。)


还是我需要一个同步的列表来让它工作


你不必走那么远。你所需要做的就是确保在适当的时候有一种“先发生后发生”的关系,并且有多种方法来实现这一点。例如,如果列表是由writer线程创建和写入的,那么writer会在对其调用
start()
之前将列表传递给reader线程对象。

如果您只是要进行读取,那么它是线程安全的。如果它是不可变的LinkedList,则保证安全。嗯。。。我不认为存在不可变的LinkedList。LinkedList类(不是子类)的任何实例都是固有可修改的。你甚至不能保证列表不会被更改,因为你提到了在迭代之前需要围栏。它似乎是那些“百万分之一”的虫子之一,但这些吸盘真的会导致糟糕的一天。@pst-是的,它是那些“百万分之一”的虫子之一。但在实际负载下,这种情况也更可能发生在多核系统上;i、 在生产中!什么是充分同步?假设我有一个初始化linkedList的主线程(此后没有线程会修改linkedList),然后主线程会生成所有只读取linkedList的线程的所有读线程(调用thread.start)。当我确定要读取的线程是在以后创建的时,是否足够“同步”呢?或者我需要调用一些神奇的方法(在这种情况下,它的名称是什么?),以便Java刷新它的内部缓存?@VitBernatik-请在另一个问题中提问。(并提供示例代码,以确保我们理解您的要求。)因此,我在这里提出了以下问题: