用于Java的AbstractQueuedSynchronizer
包中的concurrent.locks
是什么?有人可以对其方法doAcquireInterruptibly
和parkAndCheckInterrupt
?
答案 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将尝试获取锁定。如果某个其他线程已经获取了锁,则当前线程将被阻塞(停放)。如果它获得锁定,它将只返回。
答案 2 :(得分:3)
我想用一些简单的词来谈论AbstractQueuedSynchronizer(AQS)。
在现实世界中考虑这些场景:
正如我们所见,有3个变量:
AQS是一个用于管理CRITICAL SECTION的模板类,这意味着你可以扩展它并填写上面的变量来完成你的工作。隐藏了如何避免种族危险或控制队列等细节。
为了进一步阅读,您最好学习Mutex,Semaphore和ReentrantReadWriteLock的源代码。