我正在构建一个多线程应用程序,使用WorkerThreads来处理来自BlockingQueues的任务。工作者看起来像follws(作为抽象类。子类实现processItem())。
abstract class WorkerThread extends Thread {
BlockingQueue<Task> q;
int tasksInSystem; // globally available
public void run() {
while(!interrupted()) {
Task t = q.take();
process(t);
tasksInSystem--;
}
}
abstract void process(Task t);
}
特别的是,我想等待所有任务完成。 我的第一个想法是:
但: 但是有不同类型的任务和不同的工作者实现和多个队列。所以我必须维持大量不同的柜台。
我想拥有的内容:
q.waitForEmptyAndCompleted()
这将要求队列跟踪任务&#34;在飞行中&#34;并要求工作进程在完成时发出信号(而不是tasksInsystem---;
)。
工作人员无法增加该计数器,因为他必须在从队列中取出任务后计算任务。但是另一个线程可能会在take()调用之后立即运行,这样工作者就无法事先增加计数器。
因此,计数器增加和take()必须绑在一起(atomar)。这让我想到了一个专门的BlockingQueue。
我没有找到预制的解决方案。所以我最好的猜测是实现我自己的BlockingQueue。有没有我可以使用的东西(为了避免自己实现和测试线程安全的阻塞队列)?或者您是否有任何想法以不同方式实施等待呼叫?
答案 0 :(得分:1)
好的,由于一般ExecutorService
不够,ForkJoinPool
可能会起作用,它不会显式地公开队列,但是根据你所描述的内容应该非常容易使用。
密钥方法是awaitQuiescence(long timeout, TimeUnit unit)
,它将等待所有提交的任务完成执行。