如何在Java中对许多单线程队列进行线程池化?

时间:2016-03-01 08:43:21

标签: java multithreading queue

我们的应用程序需要大约10,000个并行工作队列,每个队列都具有以下特征:

  1. 必须保证队列项的处理顺序。即在从同一队列中挑选下一个项目之前,必须完成对一个已挑选项目的处理。
  2. 队列每隔3-5分钟就有一个新条目,所以空闲时间很长。
  3. 不同的队列完全独立(除了他们正在写入同一个数据库;没有共享行)。
  4. Naiv方法将拥有10.000个专用的单线程执行程序(来自Executors.newSingleThreadExecutor)。但是根据我的理解,这样的执行器与线程有1:1的关系,导致10,000个主要是空闲线程。

    目前,我们正在使用Apache ActiveMQ,但希望摆脱这一基础设施。

    任何更聪明的建议?谢谢!

1 个答案:

答案 0 :(得分:0)

没有理由需要一个线程来为每个队列提供服务。

一个简单的解决方案是拥有一些合理数量的轮询队列的线程:

final Queue<WorkItem>[] queues = ...;

public void run() {
    while (true) {
        for (Queue<WorkItem> queue : queues) {
            WorkItem workItem = queue.poll();
            if (workItem) {
                workItem.doWork();
            }
            Waitabit();
        }
    }
}

private static void Waitabit() {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ex) {
        throw new RuntimeException();
    }
}

在更复杂的解决方案中,您可以通过使用队列外部的某些方法来消除轮询的需要,以便在有工作要做时通知工作线程。

但是等等!为什么10,000个并行队列?为什么不是一个队列,每个队列项目都知道它属于哪个10,000个类别?