以ArrayList为元素的并发队列数据结构

时间:2019-06-02 22:53:06

标签: java multithreading concurrency thread-safety

详细问题

在使用数据结构(例如ArrayBlockingQueue<ArrayList<MyClass>>
时,会引起任何问题) 有多个线程?

背景

总体而言,我正在努力实现我有一个生产商来生产庞大的清单。为了加快处理。我决定使用多个使用者(线程)来消耗生产者产生的巨型列表。

我的提案解决方案

我将把巨型列表转换为多个相对较小的列表,并且为了确保其线程安全,我会将这些较小的列表排队到并发数据结构中。因此,在多线程方案中,每个线程仅轮询并发队列以获取一个列表并对其进行处理。

问题陈述

在多线程场景中,我知道我们必须使用并发数据结构来避免线程干扰并建立先发生后关系。

  • 但是将非线程安全数据结构用作线程安全数据结构的元素是否安全?

  • 在使用数据结构(例如ArrayBlockingQueue<ArrayList<MyClass>>
    时,会引起任何问题) 有多个线程?

  • 对性能会有影响吗?

2 个答案:

答案 0 :(得分:2)

这种方法应该不会出现明显的问题。

  

将非线程安全的数据结构用作线程安全的数据结构的元素是否安全?

这是安全的,只要您适当协调(或避免)对非线程安全内部数据结构的并发访问即可。 peek确保您通过pollArrayBlockingQueue<ArrayList<MyClass>>或相关方法中的一个访问其元素时建立先发生关系。

  

在多线程中使用数据结构,例如ArrayBlockingQueue<MyClass>时,会引起任何问题吗?

否,这是BlockingQueue的用途,只要您协调对内部列表的访问(请参见上文)。

  

会对性能产生影响吗?

通常,单个生产者将列表划分为子列表的方法可能不是最佳方法。生产者不/不应该知道使用者的数量及其带宽,因此通常不知道哪种分区大小能很好地工作。更好的方法可能是使用maxElements,并且从消费者方面始终通过为适当数量的{{1}}的元素调用drainTo一次消耗多个元素。

答案 1 :(得分:0)

感谢michid @和Thilo @的回答

最终分辨率

我最终使用LinkedBlockingQueue<List<MyObjClass>>并从队列中轮询了多个子线程。每个子线程都将使用MyObjClass列表进行处理。

此分辨率不会降低性能。
关于我为什么选择LinkedBlockingQueue而不是ArrayBlockingQueue的原因,请参见Link