Java并发系统中的AbstractQueuedSynchronizer

Java并发系统中的AbstractQueuedSynchronizer,java,concurrency,synchronized,Java,Concurrency,Synchronized,Java的concurrent.locks包中的AbstractQueuedSynchronizer用于什么?有人能解释一下它的方法doaquireinruptibly和parkAndCheckInterrupt concurrent.locks包中使用的AbstractQueuedSynchronizer是什么 为了 AbstractQueuedSynchronizer是在java.util.concurrency包中使用和实现(至少)的同步构造的构建块 例如,ReentrantLock委托给

Java的
concurrent.locks
包中的
AbstractQueuedSynchronizer
用于什么?有人能解释一下它的方法
doaquireinruptibly
parkAndCheckInterrupt

concurrent.locks包中使用的AbstractQueuedSynchronizer是什么 为了

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

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

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(例如,该锁要求拥有该锁的线程是释放该锁的线程,但信号量不是)

有人能解释一下它的方法是如何以不可破坏的方式获得的吗 驻车检查中断

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

doAcquireInterruptibly
将尝试成为此同步的唯一所有者。它将永远这样做,直到线程被中断或成功获取。考虑一个线程试图进入<代码>同步< /代码>块,线程将永远坐在那里等待,直到它进入监视器(当前没有线程或拥有线程存在监视器)。这里的优点是可以中断获取线程

parkAndCheckInterrupt
这只是一种方便的方法,它将暂停(停止)线程,并在重置中断状态时返回。

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

  • doAcquireInterruptibly将尝试获取锁。如果锁已经被其他线程获取,那么当前线程将被阻塞(停止)。如果它获得了锁,它将简单地返回

  • parkAndCheckInterrupt将停止线程,或者换句话说,禁用线程调度,直到其他线程取消阻止它。这可能是由于拥有锁的线程释放了锁,也可能是由于其他线程中断了锁。如果它被其他线程中断,将抛出异常

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

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

  • 对于游泳者,他们可以一起在游泳池中游泳(共享)。但是 对于将用氯消毒的清洁工来说,他必须等待 直到所有的游泳者都离开(独家
  • 对于那些 在繁忙的停车场外,他们必须排队等候。通常门卫控制出入。一辆普通汽车将占用一个停车位。林肯豪华轿车可能需要两辆或两辆以上
如我们所见,有3个变量:

  • 资源总量
  • 每次你需要多少资源
  • 访问策略(共享/独占)
  • AQS是一个模板类,用于管理关键部分,这意味着您可以扩展它并使用上面的变量进行填充,以完成您的工作。如何避免比赛危险或控制队列等细节已被隐藏


    为了进一步阅读,您最好学习互斥、信号量和ReentrantReadWriteLock的源代码。

    Aah!谢谢约翰。。。伟大的Explanation@Hemanshu:如果此答案对您有帮助,请将其标记为已接受。这是对那些帮助你的人表示感谢的一种标志,也是一种指导其他有这个问题的人的方式。