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?
4

3 回答 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();
     }
}

最后,当你 catchInterruptedException时立即重新中断线程是一个很好的模式,因为当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
}
于 2013-04-03T13:30:32.197 回答
0

调用put将等待插槽空闲,然后再添加param并且流程可以继续。

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

这个例子有类似的东西,它负责在给定的超时后调用中断。

于 2013-04-03T13:31:06.080 回答
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();
于 2013-04-03T13:37:57.920 回答