ArrayBlockingQueue - 如何“中断”正在等待.take()方法的线程

时间:2010-06-05 03:41:33

标签: java concurrency

我在代码中使用ArrayBlockingQueue。客户端将等待元素可用:

myBlockingQueue.take();

如果队列中没有元素并且take()无限期地等待元素变为可用,我如何“关闭”我的服务?此方法抛出InterruptedException。我的问题是,我怎样才能“唤起”一个中断的异常,以便take()退出? (我也谈到了notify(),但似乎我在这里没有帮助..)

我知道我可以插入一个特殊的“EOF / QUIT”标记元素,但这真的是唯一的解决方案吗?

更新(关于评论,指出另一个问题有两个解决方案):

上面提到的一个使用“中毒丸对象”,第二个是Thread.interrupt()

myBlockingQueue.take()Thread(扩展线程)中使用 NOT ,而是实现Runnable。似乎Runnable没有提供.interrupt()方法?

我怎样才能打断Runnable

3 个答案:

答案 0 :(得分:5)

您可以像这样实现Runnable。 (它假设您在尝试中断之前启动了Runnable)

class MyRunnable implements Runnable {
    private Thread thisThread;
    public void run() {
       thisThread = Thread.currentThread();
       try {
          // do some work
       } catch(Throwable t) {
          t.printStackTrace(); // or log the error.
       } 
    }
    public void interrupt() {
       thisThread.interrupt();
    }
}

答案 1 :(得分:1)

直接的方法是保留用于运行runnable的线程的引用,并在关闭时中断它。

或者,您可以使用线程池来组织服务的线程。然后,线程池负责跟踪线程并管理它们,包括在关闭时中断它们。

另一种(hacky且不推荐的方式)方法是枚举JVM中的所有正在运行的线程(使用ThreadGroup的方法)并尝试猜测哪个线程运行您的runnable(例如,通过分析每个线程的堆栈)。

答案 2 :(得分:0)

找到解决方案:

使用,如问题中描述的“中毒对象”

使用this.interrupt()中断线程eitehr,或者如果它是Runnable使用Thread.currentThread().interrupt();