2

I'm thinking how to implement the producer/consumer pattern in Java.

Assume that I have 3 threads and a List containing tasks (say it's about 5 tasks). Each thread grab the task from the list and execute it concurrently. My current approach is to use CountDownLatch

int N = 3;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
ConcurrentLinkedQueue<String> tasks = new ConcurrentLinkedQueue<String>();

main() {
    for (int i=0;i<N;i++) {
        new Thread(new Worker()).start();
    }
    startSignal.countDown();
    doneSignal.await();
    System.out.println("done");
}

class Worker implements Runnable {
    public void run() {
        startSignal.await();
            while ((s = tasks.poll()) != null) {
                // do lengthy task here
                if (task failed) {
                    tasks.add(s);
                    return; // assume that task fails badly and have to stop the thread
                }
            }
        doneSignal.countDown();
    }
}

what I wanted to achieve is that if a thread fails when processing a task, it will be added back to the task list to be picked up again by current or any other thread, but with my current approach using CountDownLatch obviously it is not possible to do so because after doneSignal.countDown() is called, the thread assumes it already have finished the task.

What would be the best approach for this scenario? Is using Executor the only way?

4

1 回答 1

3

对于这种情况,我想说这是一个过于复杂(并且容易出错)的解决方案,使用通用的 BlockingQueue 会更简单,单线程从这个阻塞队列轮询并将作业移交给 ExecutorService。

看不出在这种情况下为什么需要 CountDownLatch 的任何原因,它只是不必要地使您的工作人员复杂化,必须了解它在线程环境中运行并且还必须在完成时清理任何脏东西。BlockingQueues 和 ExecutorServices 正是为了让您摆脱这些问题。

于 2011-08-15T04:25:03.973 回答