在循环中调用可中断的阻塞方法

GJ13

这个问题来自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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在方法调用之前中断阻塞方法

来自分类Dev

Python从for循环中的可迭代值调用类方法

来自分类Dev

在循环中调用 ssh 命令时 bash 循环中断

来自分类Dev

如何中断在循环内阻塞的可调用线程?

来自分类Dev

阻塞IO方法在while循环中抛出NoSuchException - Java

来自分类Dev

在foreach()循环中中断if

来自分类Dev

如何在循环中调用keyPressed()方法?

来自分类Dev

循环中嵌套对象的JavaScript调用方法

来自分类Dev

在 v-for 循环中调用方法

来自分类Dev

循环中断在结束之前

来自分类Dev

如何避免循环中断?

来自分类Dev

java循环中断与if语句?

来自分类Dev

Java中的循环中断

来自分类Dev

延迟 for 循环中断函数

来自分类Dev

在循环中中断 <option> 项

来自分类Dev

用循环中断程序

来自分类Dev

阻塞线程的调用方法

来自分类Dev

如何避免循环中的代码阻塞

来自分类Dev

为什么 if 语句在 while 循环中阻塞?

来自分类Dev

在while循环中中断while循环

来自分类Dev

循环python中的循环中断

来自分类Dev

在for循环中调用setNeedsDisplay

来自分类Dev

在for循环中调用对象

来自分类Dev

逻辑应用程序,直到HTTP调用收到400后循环中断

来自分类Dev

按下键可中断循环

来自分类Dev

在文档中,如果BluetoothServerSocket.accept()仍然阻塞了线程,为什么会在while循环中调用它?

来自分类Dev

Angular 2-在模板循环中调用类方法* ngFor

来自分类Dev

当集合为空时,RoR在循环中调用方法

来自分类Dev

在C#中,每个循环中的foreach调用方法吗?