我正在阅读"实践中的并发",在第6章的"响应中断"下,它说
"过早设置中断状态可能会导致无限循环,因为大多数可中断阻塞方法在进入时检查中断状态,如果设置了中断异常,则立即抛出中断异常。(可中断方法通常在阻塞或执行任何重要工作之前轮询中断,以便在阻止或执行任何重要工作之前对中断做出响应,以便尽可能对中断做出响应(">
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
假设代码是
public Task getNextTask(BlockingQueue<task> queue){
boolean interrupted=false;
while(true){
/*i get this part that before the take() function threads interrupted status is checked*/
return queue.take();
}catch(InterruptedException e){
interrupted=true;
Thread.currentThread().interrupt();
}
}//end of while
}
现在为什么最后一个函数会导致无限循环,因为我已将 threrad 的中断状态设置回 false,根据我的理解,在阻塞调用轮询线程的中断状态期间,它将检查它是否已设置,它会发现它为 false,然后继续调用。那么无限循环是从哪里来的呢?
将抛出InterruptedException
,因为take()
方法检查中断。此检查/抛出通常采用以下形式:
if (Thread.currentThread.interrupted()) { // Checks and clears the interrupted flag.
throw new InterruptedException();
}
然后,您捕获InterruptedException
,恢复中断标志,并再次呼叫take()
。这将检查中断,发现线程已被中断,然后抛出InterruptedException
。
然后,您捕获InterruptedException
,恢复中断标志,并再次呼叫take()
。这将检查中断,发现线程已被中断,然后抛出InterruptedException
。
然后,您捕获InterruptedException
,恢复中断标志,并再次呼叫take()
。这将检查中断,发现线程已被中断,然后抛出InterruptedException
。
等。