Java并发中的AbstractQueuedSynchronizer

时间:2012-03-10 07:52:03

标签: java concurrency synchronized

用于Java的AbstractQueuedSynchronizer包中的concurrent.locks是什么?有人可以对其方法doAcquireInterruptiblyparkAndCheckInterrupt

有所了解

3 个答案:

答案 0 :(得分:10)

  

在concurrent.locks包中使用的是什么是AbstractQueuedSynchronizer   对

AbstractQueuedSynchronizer是java.util.concurrency包中使用和实现(至少)的同步构造的构建块。

例如,ReentrantLock委托给扩展AbstractQueuedSynchronizer的Sync。如果您要编写自己的锁,它可能看起来像这样

public class MyLock extends AbstractQueuedSynchronizer implements Lock{
    @Override
    public void lock() {
        super.acquire(1);
    }
    @Override
    public void unlock() {
        if(Thread.currentThread() != super.getExclusiveOwnerThread())
            throw new IllegalMonitorStateException();
        super.release(1);
    }
}

所以这里的MyLock类将继承线程暂停和放大器的低级功能。在处理任何特殊功能本身时排队到AQS(例如,这个锁需要拥有锁的线程是释放它的线程,但是信号量没有)。

  

有人可以对其方法有所了解吗   parkAndCheckInterrupt

注意:这些方法对于类是私有的,因此实际功能可以在不同版本或不同实现之间进行更改。我在解释时提供的默认功能如下:

doAcquireInterruptibly将尝试成为此同步的独占所有者。它将永远执行此操作,直到线程被中断或成功获取。考虑一个线程试图进入synchronized块,线程将坐在那里并等待它直到它进入监视器(当前没有线程拥有或监视器存在拥有线程)。这里的优点是可以中断获取线程。

parkAndCheckInterrupt只是一种方便方法,可以暂停(暂停)一个线程,在重置中断状态时返回。

答案 1 :(得分:7)

  • AbstractQueuedSynchronizer:它提供了一个框架,用于实现阻塞锁和相关的同步器,如信号量,CountDownLatch等。获取的基本算法是try acquire,如果成功则返回else入队线程,如果它尚未排队并阻塞当前线程。同样,发布的基本算法是try release,如果成功,则取消阻塞队列中的第一个线程,否则只返回。线程将在先进先出(FIFO)等待队列中等待。抽象方法tryAcquire和tryRelease将根据需要由子类实现。

  • doAcquireInterruptibly将尝试获取锁定。如果某个其他线程已经获取了锁,则当前线程将被阻塞(停放)。如果它获得锁定,它将只返回。

  • parkAndCheckInterrupt将停放线程或换句话说禁用线程调度,直到某个其他线程解除阻塞。这可能是由于拥有线程释放锁定或由于某些其他线程中断它。如果它被某个其他线程中断,则会抛出异常。

答案 2 :(得分:3)

我想用一些简单的词来谈论AbstractQueuedSynchronizer(AQS)。

在现实世界中考虑这些场景:

  • 对于游泳运动员,他们可以在游泳池里一起游泳(分享)。但 对于那些用氯思考来清洁它的清洁工,他必须等待 直到所有游泳者都离开了(独家)。
  • 对于那些司机 在繁忙的停车场外,他们必须排队等候。通常门卫控制访问。普通汽车将占用一个停车位。林肯豪华轿车可能需要两个或更多

正如我们所见,有3个变量:

  1. 总资源数量。
  2. 每次服用多少资源。
  3. 访问策略(共享/独占)。
  4. AQS是一个用于管理CRITICAL SECTION的模板类,这意味着你可以扩展它并填写上面的变量来完成你的工作。隐藏了如何避免种族危险或控制队列等细节。

    为了进一步阅读,您最好学习Mutex,Semaphore和ReentrantReadWriteLock的源代码。