Search code examples
javaandroidconcurrencyblockinginterrupt

How to interrupt BlockingQueue?


BlockingQueue.put can throw InterruptedException. How can I cause the queue to be interrupting by throwing this exception?

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?

Solution

  • You need to interrupt the thread that is calling the queue.put(...);. The put(...); call is doing a wait() on some internal condition and if the thread which is calling the put(...) gets interrupted, the wait(...) call will throw InterruptedException which is passed on by the put(...);

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

    To get the thread you can either store it when it is created:

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

    or you can use the Thread.currentThread() method call and store it somewhere for others to use to interrupt.

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

    Lastly, it is a good pattern when you catch InterruptedException to immediately re-interrupt the thread because when the InterruptedException is thrown, the interrupt status on the thread is cleared.

    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
    }