Java并发中的AbstractQueuedSynchronizer

Hem*_*shu 8 java concurrency synchronized

什么是concurrent.locks包中的AbstractQueuedSynchronizer用于?有人可以对其方法doAcquireInterruptibly和parkAndCheckInterrupt进行一些说明吗?

Joh*_*int 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  • @Hemanshu:如果这个答案对您有帮助,请将其标记为已接受。这是对那些帮助你的人的感激之情,也是一种指导其他有这个问题的人的方式。 (2认同)

Sat*_*ish 7

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

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

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


And*_*son 5

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

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

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

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

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

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

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