如何中断BlockingQueue?

3

BlockingQueue.put可能会抛出InterruptedException异常。 我该如何通过抛出此异常来中断队列?

ArrayBlockingQueue<Param> queue = new ArrayBlockingQueue<Param>(NUMBER_OF_MEMBERS);
...
try {
    queue.put(param);
} catch (InterruptedException e) {
    Log.w(TAG, "put Interrupted", e);
}
...
// how can I queue.notify?
3个回答

7

你需要中断调用 queue.put(...); 的线程。 put(...); 调用正在某些内部条件上执行 wait(),如果调用 put(...) 的线程被中断,则 wait(...) 调用将抛出 InterruptedException 异常,该异常由 put(...); 传递。

// interrupt a thread which causes the put() to throw
thread.interrupt();

要获取线程,您可以在创建时将其存储:

Thread workerThread = new Thread(myRunnable);
...
workerThread.interrupt();

或者你可以使用Thread.currentThread()方法调用并将其存储在某个位置供其他人使用以进行中断。

public class MyRunnable implements Runnable {
     public Thread myThread;
     public void run() {
         myThread = Thread.currentThread();
         ...
     }
     public void interruptMe() {
         myThread.interrupt();
     }
}

最后,当你捕获到InterruptedException时,立即重新中断线程是一个好的模式,因为当抛出InterruptedException时,线程上的中断状态会被清除。
try {
    queue.put(param);
} catch (InterruptedException e) {
    // immediately re-interrupt the thread
    Thread.currentThread().interrupt();
    Log.w(TAG, "put Interrupted", e);
    // maybe we should stop the thread here
}

0

你需要引用使用queue.put()运行代码的线程,就像这个测试中一样。

    Thread t = new Thread() {
        public void run() {
            BlockingQueue queue = new ArrayBlockingQueue(1);
            try {
                queue.put(new Object());
                queue.put(new Object());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
    };
    t.start();
    Thread.sleep(100);
    t.interrupt();

0

调用put将等待一个空闲的插槽,然后添加param并继续流程。

如果在调用put时捕获正在运行的线程(即,在调用put之前调用Thread t1 = Thread.currentThread()),然后在另一个线程上调用interrupt(当t1被阻塞时)。

此示例类似于在给定超时后调用中断。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接