0
点赞
收藏
分享

微信扫一扫

Java AQS详解

  AQS(AbstractQueuedSynchronizer)是Java并发编程中的一个重要组件,提供了一种实现锁和同步器的框架,它是Java并发编程中非常重要的一部分。

一、AQS介绍

    实现锁和同步器的框架,是Java并发编程中非常重要的一部分。它提供了一些基本的同步操作,例如获取锁、释放锁、线程阻塞等,同时也允许开发人员自定义同步器。在Java中,ReentrantLock、Semaphore、CountDownLatch等同步器都是基于AQS实现的。

    基于FIFO队列的等待队列,当线程无法获取同步器时,它将被加入到等待队列中。当同步器状态改变时,例如释放锁,等待队列中的线程将被唤醒并尝试重新获取同步器。

二、AQS特性

1. 状态变量

    0表示未被任何线程持有,非0表示被某个线程持有。

2. 等待队列

    当同步器状态改变时,等待队列中的线程将被唤醒并尝试重新获取同步器。

3. 共享锁和独占锁

    支持共享锁和独占锁,共享锁可以被多个线程同时获取,而独占锁只能被一个线程获取。例如,ReadWriteLock就是基于AQS实现的共享锁和独占锁。

4. 可重入

    一个线程可以多次获取同一个锁而不会被阻塞,这可以避免死锁和提高性能。

5. 条件变量

    允许线程在等待队列中等待某个条件满足后再继续执行。

三、AQS重要方法

1. acquire

    它首先会尝试快速获取锁,如果失败则加入等待队列。如果获取失败后,该方法会通过自旋和线程阻塞的方式等待锁的释放。当锁被释放时,它会尝试再次获取锁。在获取锁的过程中,该方法会调用tryAcquire方法,该方法用于尝试获取锁。

2. release

    会调用tryRelease方法,该方法用于释放锁。

3. acquireShared和releaseShared

    用于共享锁的获取和释放,与独占锁的获取和释放类似。

四、AQS的同步流程

1. 公平锁

    公平锁是Java中一种比较公平的锁,它通过严格按照线程请求锁的顺序来获取锁,从而保证所有线程有平等的机会获取锁。公平锁的实现流程如下:

    (1) 当一个线程请求获取锁时,它首先会被加入到同步器的等待队列中。

    (2) 然后,该线程会在等待队列中尝试获取锁,如果当前没有任何线程持有锁,该线程将成为锁的拥有者,否则它将继续等待。

    (3) 当锁被释放时,同步器将从等待队列中取出等待时间最久的线程,并让该线程尝试获取锁。这保证了所有等待锁的线程能够获得锁。

2. 非公平锁

    非公平锁是Java中一种不太公平的锁,它允许线程在竞争锁时直接获取锁,而不必按照请求锁的顺序等待。非公平锁的实现流程如下:

    (1) 当一个线程请求获取锁时,它会尝试以非公平的方式获取锁,这意味着如果当前没有任何线程持有锁,该线程将直接成为锁的拥有者。

    (2) 如果当前有其他线程持有锁,该线程将加入到同步器的等待队列中,并按照请求锁的顺序排队等待。

    (3) 当锁被释放时,同步器将从等待队列中取出队首的线程,并让该线程尝试获取锁。如果线程在等待队列中的位置比较靠后,它有可能被跳过,直接让后面的线程获取锁。

    (4) 如果有后续线程等待获取锁,它们仍然会按照先后顺序排列,因此有可能某些线程会一直等待,无法获取锁。

    公平锁的实现更加公平,但是会导致锁的竞争增加,从而降低性能。相比之下,非公平锁的实现更加高效,但可能会导致一些线程一直等待,无法获取锁。可以根据自己的需求和并发性能选择适合自己的同步方式。

五、AQS使用案例

1. ReentrantLock介绍和使用

2. Semaphore介绍和使用

3. CountDownLatch介绍和使用

举报

相关推荐

0 条评论