Java 如何中断阻塞队列?

Java 如何中断阻塞队列?,java,android,concurrency,blocking,interrupt,Java,Android,Concurrency,Blocking,Interrupt,BlockingQueue.put可能引发InterruptedException。 如何通过抛出此异常来中断队列 ArrayBlockingQueue<Param> queue = new ArrayBlockingQueue<Param>(NUMBER_OF_MEMBERS); ... try { queue.put(param); } catch (InterruptedException e) { Log.w(TAG, "put Interrupt

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?
ArrayBlockingQueue=新的ArrayBlockingQueue(成员的数量);
...
试一试{
queue.put(param);
}捕捉(中断异常e){
Log.w(标签“放置中断”,e);
}
...
//如何排队通知?

您需要中断调用
队列的线程。put(…)
put(…)调用在某些内部条件下执行
wait()
,如果调用
put(…)
的线程被中断,
wait(…)
调用将抛出
InterruptedException
,该异常由
put(…)传递

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

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
}

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

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


具有类似的功能,它负责在给定超时后调用中断。

您需要使用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();
    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();