用于在工作线程之间分配作业的队列类型

时间:2013-08-12 11:55:19

标签: java multithreading queue

我是java新手,我想编写一个线程库作为练习。它将以这种方式工作,

在主线程中,一些作业(作为字符串)将被添加到作业队列中,当工作线程完成作业时,它会将其添加到已完成的队列中。主线程将从完成的队列中获得结果。完成所有工作后,主线程将指示工人停止工作。以下是我到目前为止编写的一些代码:

public List<int> get() {
    WorkerThread[] threads = new WorkerThread[numThreads];
    LinkedList<int> results = new LinkedList<>();
    int workCount = 0;

    for (int i = 0; i < numThreads; i++) {
        threads[i] = new WorkerThread();
        threads[i].start();
    }
    // reader is a BufferedReader
    while ((String line = reader.readLine()) != null) {
        // put string to job queue
        workCount++
    }
    while(workCount) {
        //result = get result from finished queue, and add it to results LinkedList
        workCount--;  
    }
    for (int i = 0; i < numThreads; i++) {
        threads[i].canStop(); // this sets a private variable that makes infinite while loop to stop
        threads[i].join();
    }
    return results;
}

但我对使用什么样的Queue实现感到困惑。由于documentation显示了11种不同的队列实现。

3 个答案:

答案 0 :(得分:1)

ConcurrentLinkedQueue 是基于链接节点的无限制线程安全队列。

  

当许多线程共享对a的访问权限时,这是一个合适的选择   常见集合但此类不允许使用null   元件。

link包含可用于多线程的不同队列实现之间的比较。

答案 1 :(得分:1)

如果多个线程访问同一个队列(实际上它们都是Queue实现),则建议在java.util.concurrent中实现所有BlockingQueue的实现。即使是只读函数(否则您可能会有两个线程从队列中轮询相同作业并执行它的风险)。也就是说,如果您不想花费大量时间自己同步访问(并测试同步)。

然后选择取决于您在队列中需要的额外功能。 LinkedBlockingQueueArrayBlockingQueue之间的差异在于各种基本操作(插入,删除,选择......)的表现。 PriorityBlockingQueue允许你根据自己的条件“推”(也就是优先级)某些工作与其他工作相比(我相信它是作为堆实现但不引用我的)。 DelayQueue做了名字所说的,它允许你将某些工作延迟一段时间。

我喜欢ConcurrentLinkedQueue,因为它使用“无等待”算法,理论上比同步(等待资源)功能更好。

另外请注意:我建议您查看ExecutorExecutorsExecutorService,而不是管理自己的主题集合。

答案 2 :(得分:0)

由于队列将从许多不同的线程访问,因此使用java.util.concurrent中的一个队列实现可能更有效。其他队列可能需要显式同步。

尝试ArrayBlockingQueue例如,它实现了一个有界环形缓冲区。它受限制这一事实意味着当作业提交速度超过可处理速度时,它会自动应用背压;在你内存不足之前,队列不会继续增长。

实现的不同之处主要在于性能特征,不同的作业负载可能会受益于不同的队列。您应该测试哪种选项最适合您的情况。