1

以下是阻塞队列的单个使用者的简单实现。我的问题是,我应该需要哪些额外的代码才能使其投入生产?假设我需要这个消费者永远留在身边。

几个问题,例如:

  1. while(true) 是否足够好?
  2. 当我得到一个 InterruptedException 时该怎么办,以便我可以尝试恢复我正在做的事情?
  3. 如果线程挂起会发生什么?
  4. 如果线程由于异常而终止会发生什么?

我想我的总体问题是关于实现对这个单线程消费者的管理和监控的一些想法。或者是否存在提供基本实现的现有库。

非常感谢!

public class Consumer implements Runnable{

    private BlockingQueue queue;

    public Consumer (BlockingQueue queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            try {
                Object task = queue.take();
                ...
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
    }
}
4

2 回答 2

4

while(true) 是否足够好?

哎呀。@Cratylus 提出了一个很好的观点,您应该始终使用:

 while (!Thread.currentThread().isInterrupted()) {

你需要对异常的捕捉保持虔诚——甚至可能捕捉RuntimeException,甚至可能Throwable。至少您应该考虑在退出之前捕获并记录一条消息。

当我得到一个 InterruptedException 时该怎么办,以便我可以尝试恢复我正在做的事情?

这取决于您希望线程做什么。IMO,当一个线程被中断时,它应该(呃)被中断。由于thread.stop()许多原因已弃用,thread.interrupt()所以真的是阻止线程运行的唯一方法。这意味着它应该清理并退出。

} catch (InterruptedException ex) {
    // always a good practice to re-interrupt
    Thread.currentThread().interrupt();
    // but now what to do?  I vote for stopping the thread
    return;
}

如果线程挂起会发生什么?

除非您的程序中有错误,否则这永远不会发生。它可能会永远等待,queue.take()但中断应该将其踢出。

注意多个synchronized部分以防止死锁。请务必使用java.util.concurrent.*类 ( BlockingQueue, Executors, ...) 来教训用户代码导致问题的机会。使用Atomic*类。线程之间共享的所有数据都需要正确synchronizedvolatile.

如果线程由于异常而终止会发生什么?

你想发生什么?如果这是你想做的,你应该(再次)虔诚地捕捉异常。如果您希望线程在看到异常时停止,那么我会捕获异常,记录它,然后清理并返回。异常处理没有简单的答案。

于 2013-01-23T21:40:02.987 回答
3

while(true) 是否足够好?

不,你应该这样做while(!interrupted)

当我得到一个 InterruptedException 时该怎么办,以便我可以尝试恢复我正在做的事情?

如果你得到一个中断的异常,你不应该恢复。这是停止的信号

如果线程挂起会发生什么?

如果您在中断时退出,则不会。它将以您当前的形式挂起(由于您当前已对其进行编码,因此无法阻止它)

如果线程由于异常而终止会发生什么?

它终止了。不确定你的意思。

于 2013-01-23T21:41:34.947 回答