AQS(AbstractQueuedSynchronizer)框架在Java并发编程中提供了一种灵活的机制来实现同步器,它支持两种主要的资源共享方式:独占(Exclusive)和共享(Shared)。
独占方式(Exclusive)
在独占方式下,资源在任意时刻只能被一个线程所持有。这种方式通常用于实现互斥锁,如ReentrantLock。当一个线程成功获取到独占锁时,它会阻塞其他所有尝试获取该锁的线程,直到持有锁的线程释放锁为止。在AQS中,独占锁通过维护一个同步状态(通常是一个volatile int类型的变量)来表示锁是否被某个线程持有。
共享方式(Shared)
在共享方式下,资源可以被多个线程同时访问。这种方式通常用于实现如信号量(Semaphore)、读写锁(ReadWriteLock)中的读锁等同步器。在共享模式下,AQS的同步状态通常表示可用资源的数量。当一个线程尝试获取共享资源时,它会检查同步状态的值,并尝试减少可用资源的数量(这通常是通过原子操作来完成的)。如果同步状态的值表明有足够的资源可供使用(即减少后的值仍然非负),则线程成功获取资源并继续执行。如果同步状态的值表明没有足够的资源可供使用,则线程可能会被放入等待队列中等待,直到其他线程释放资源并更新同步状态。
实现细节
- 状态管理:AQS使用一个
volatile int变量来存储同步状态,以确保线程间的可见性。 - 等待队列:AQS内部维护了一个等待队列(也称为同步队列),用于存放等待获取同步资源的线程。等待队列是一个双向链表结构,每个节点代表一个等待获取锁的线程。
- 获取和释放:对于独占锁,AQS提供了
acquire()方法来获取锁,release()方法来释放锁。对于共享锁,AQS提供了acquireShared()方法来获取共享资源,releaseShared()方法来释放共享资源。这些方法在内部会根据独占或共享模式调用相应的tryAcquire()、tryRelease()、tryAcquireShared()和tryReleaseShared()等方法,这些方法需要在子类中实现具体的同步逻辑。
应用场景
- 独占锁:如
ReentrantLock,用于确保一次只有一个线程能够执行某段代码或访问某个资源。 - 共享锁:如
Semaphore用于限制同时访问某个资源的线程数量,读写锁中的读锁允许多个线程同时读取资源,但写锁是独占的。
通过理解AQS的资源共享方式,开发者可以更加灵活地设计并发程序,以满足不同的同步需求。
170万+

被折叠的 条评论
为什么被折叠?



