这个问题来自Brian Goetz的“ Java并发性实践”一书的第7章,第7.1.3节,对中断的响应(第143-144页)
不支持取消但仍调用可中断阻塞方法的活动将必须在循环中调用它们,并在检测到中断时重试。在这种情况下,他们应该在本地保存中断状态,并在返回之前立即恢复状态,如下例所示,而不是在捕获InterruptedException时立即将其恢复。将中断状态设置为太安全可能会导致无限循环,因为大多数可中断的阻塞方法都会在进入时检查中断状态,如果设置了此状态,则立即抛出InterruptedException。
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
我的问题是为什么需要循环?
另外,如果queue.take()抛出interruptedException,那么我假设当前线程上的中断标志设置正确吗?然后,由于未清除当前线程上的前一个中断,因此对下一个对queue.take()的调用将再次引发interruptedException,这是否会导致无限循环?
回答你的第一个问题
My question is why is the loop required?
躺在这条线
Activities that do not support cancellation but still call interruptible
blocking methods will have to call them in a loop, retrying when interruption
is detected.
From Java concurrency in Practice 7.1.3
getNextTask方法不支持cancel.ie,即使线程被中断,它也不会取消它的任务,而是会重试。并请注意,getNextTask方法正在调用可中断的阻塞方法queue.take(),该方法抛出intteruptedException。getNextTask方法将必须处理interruptedException,因为它不支持取消,应该重试。简而言之,它是一种方法策略,它决定重试还是将中断的异常抛出到方法签名中。
你的第二个问题
Also if queue.take() throws an interruptedException then I am assuming the
interrupt flag is set on the current thread correct?
如果抛出中断异常,则否,将重置中断标志。
还要注意,在finally块中,线程是自中断自身(Thread.currentThread()。interrupt()),因为调用getNextTask的堆栈还可以调用其他可中断的阻塞方法,此类方法通常首先检查当前线程是否已被中断。是否打断。如果是,则重设中断标志,并引发如下所示的中断异常。
Below is the Code from AQS(AbstractQueueSynchronizer) from java
public final void acquireInterruptibly(int arg) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句