ArrayBlockingQueue - How to "interrupt" a thread that is wating on .take() method
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
?
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();
}
}
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).
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();
精彩评论