Java并发中的AbstractQueuedSynchronizer

问题描述 投票:8回答:3

什么是Java qazxsw poi包中的qazxsw poi用于?有人可以对其方法AbstractQueuedSynchronizerconcurrent.locks有所了解吗?

java concurrency synchronized
3个回答
10
投票

什么是用于的concurrent.locks包中的AbstractQueuedSynchronizer

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

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

doAcquireInterruptibly

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

有人可以对其方法doAcquireInterruptibly和parkAndCheckInterrupt进行一些说明

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

parkAndCheckInterrupt将尝试成为此同步的独家所有者。它将永远执行此操作,直到线程被中断或成功获取。考虑一个线程试图进入一个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); } } 块,该线程将坐在那里等待它直到它进入监视器(当前没有线程拥有或监视器存在拥有线程)。这里的优点是可以中断获取线程。

doAcquireInterruptibly只是一种方便方法,它将暂停(停放)一个线程,在重置中断状态时返回。


7
投票
  • AbstractQueuedSynchronizer:它提供了一个框架,用于实现阻塞锁和相关的同步器,如信号量,CountDownLatch等。获取的基本算法是try acquire,如果成功则返回else入队线程,如果它尚未排队并阻塞当前线程。同样,发布的基本算法是try release,如果成功,则取消阻塞队列中的第一个线程,否则只返回。线程将在先进先出(FIFO)等待队列中等待。抽象方法tryAcquire和tryRelease将根据需要由子类实现。
  • doAcquireInterruptibly将尝试获取锁定。如果某个其他线程已经获取了锁,则当前线程将被阻塞(停放)。如果它获得锁定,它将简单地返回。
  • parkAndCheckInterrupt将停放线程或换句话说禁用线程调度,直到其他线程解除阻塞。这可能是由于拥有线程释放锁定或由于某些其他线程中断它。如果被某个其他线程中断,则会抛出异常。

4
投票

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

想想现实世界中的这些场景:

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

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

  1. 总资源数量。
  2. 每次服用多少资源。
  3. 访问策略(共享/独占)。

AQS是一个用于管理CRITICAL SECTION的模板类,这意味着您只需扩展它并填写上面的变量即可完成工作。隐藏了如何避免种族危险或控制队列等细节。

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

© www.soinside.com 2019 - 2024. All rights reserved.