在Java中停止循环线程

hal*_*arp 7 java multithreading

我正在使用一个不断从队列中读取的线程.

就像是:

public void run() {
    Object obj;
    while(true) {
        synchronized(objectsQueue) {
            if(objectesQueue.isEmpty()) {
                try {
                    objectesQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                obj = objectesQueue.poll();
            }
        }

        // Do something with the Object obj
    }
}
Run Code Online (Sandbox Code Playgroud)

停止此线程的最佳方法是什么?

我看到两个选择:

1 - 由于Thread.stop()不推荐使用,我可以实现一个stopThisThread()使用原子检查条件变量的方法.

2 - 将死亡事件对象或类似内容发送到队列.当线程获取死亡事件时,它将退出.

我更喜欢第一种方式,但是,我不知道何时调用该stopThisThread()方法,因为它可能会出现在队列中,并且停止信号可以首先到达(不可取).

有什么建议?

Ste*_*n C 6

DeathEvent(或因为它是常说,"毒丸计划")的做法效果很好,如果你要在关闭之前完成队列上的所有工作.问题是这可能需要很长时间.

如果你想尽快停止,我建议你这样做

BlockingQueue<O> queue = ...

...

public void run() {
   try {
       // The following test is necessary to get fast interrupts.  If
       // it is replaced with 'true', the queue will be drained before
       // the interrupt is noticed.  (Thanks Tim)
       while (!Thread.interrupted()) {
           O obj = queue.take();
           doSomething(obj);
       }
   } catch (InterruptedException ex) {
       // We are done.
   }
}
Run Code Online (Sandbox Code Playgroud)

要停止t使用该run方法实例化的线程,只需调用即可t.interrupt();.

如果您将上面的代码与其他答案进行比较,您将会注意到如何使用BlockingQueueThread.interrupt()简化解决方案.

我还要求额外的stop标志是不必要的,从大局来看,可能有害.一个表现良好的工作线程应该尊重中断.意外中断只是意味着工作程序正在原始程序员没有预料到的上下文中运行.最好的事情是如果工人做了被告知要做的事情......即它应该停止......这是否符合原始程序员的概念.