0

I use an ArrayBlockingQueue in my code. Clients will wait until an element becomes available:

myBlockingQueue.take();

How can I "shutdown" my service in case no elements are present in the queue and the take() is waiting indefinitely for an element to become available? This method throws an InterruptedException. My question is, how can I "evoke" an Interrupted Exception so that take() will quit? (I also tought about notify(), but it seems I doesn't help here..)

I know I could insert an special "EOF/QUIT" marker Element but is this really the only solution?

UPDATE (regarding the comment, that points to another question with two solutions):

one mentioned above using a "Poisoning Pill Object" and the second one is Thread.interrupt():

The myBlockingQueue.take() is used NOT in a Thread (extending Thread) but rather implements Runnable. It seems a Runnable does not provide the .interrupt() method?

How could I interrupt the Runnable?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
bernhard
  • 53
  • 6
  • 1
    Very similar question: http://stackoverflow.com/questions/812342/how-to-interrupt-a-blockingqueue-which-is-blocking-on-take – Justin Ardini Jun 05 '10 at 03:43

3 Answers3

5

You can implement the Runnable like this. (It assumes you have started the Runnable before you attempt to interrupt it)

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();
    }
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

The straightforward way is to keep a reference of the thread you use to run the runnable and interrupt it on shutdown.

Alternatively you can use thread pools to organize the threads for a service. Then the threadpool takes care of keeping track of the threads and managing them, including interrupting them when shutting down.

Yet another (hacky and not recommended way) way is to enumerate all running threads in the JVM (using the ThreadGroup's method) and try to guess which thread runs your runnable (e.g. by analyzing the stack of each thread).

ddimitrov
  • 3,293
  • 3
  • 31
  • 46
0

Found the solution:

Either use, as described in the question an "Poisoning Object"

or

Interrupt the Thread eitehr with this.interrupt() or if it is a Runnable use Thread.currentThread().interrupt();

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
bernhard
  • 53
  • 6
  • First part of the answer is correct, the second is nonsense. If you execute Thread.currentThread().interrupt(), you are interrupting the current thread, and if you can execute that you are clearly not blocked anywhere else. – user207421 Jun 07 '10 at 02:34