为什么在阻止调用之前过早设置中断状态会导致无限循环?



我正在阅读"实践中的并发",在第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

等。

最新更新