存档

2015年8月 的存档

LinkedBlockingDeque中take的两个问题

2015年8月31日 没有评论

先看代码

  public E take() throws InterruptedException {
    return takeFirst();
  }

  public E takeFirst() throws InterruptedException {
    ReentrantLock localReentrantLock = this.lock;
    localReentrantLock.lock();
    try {
      Object localObject1;
      while ((localObject1 = unlinkFirst()) == null)
        this.notEmpty.await();
      Object localObject2 = localObject1;
      return localObject2;
    } finally {
      localReentrantLock.unlock();
    }
  }

问题1:当队列非空时,不会感知到被中断,也不会抛InterruptedException,除非队列空了。
有一种解释是当中断发生时,需处理完队列后才允许产生中断异常。按这种思路,生产者线程也要先检测中断,确保不会生产了,是否为空才有意义,实际上生产者并没有检验。
而带有超时时间的poll和offer操作,都会提前检查中断,用的是lockInterruptibly。
个人感觉:只要是会触发中断异常的地方,就应该用lockInterruptibly,不容易产生误解。

问题2:localObject2的存在是否有意义。
运行期经过复写传播(Copy Propagation)和无用代码消除(Dead Code Elimination)后,localObject2会直接消失,变成return localObject1;
作者这么干的意义是什么呢?感觉毫无意义。欢迎拍砖~