AQS独占锁之ReentrantLock详解

文章目录

  • 一、AQS与ReentrantLock简介
  • 二、ReentrantLock的基本使用方式
  • 三、公平和非公平锁的实现
    • ReentrantLock是如何实现公平锁和非公平锁的?
      • 代码示例:
  • 四、可重入锁的实现
    • 代码示例
  • 五、AQS的特性分析
  • 六、总结


一、AQS与ReentrantLock简介

AbstractQueuedSynchronizer(简称AQS)是一个抽象同步框架,可以用来实现一个依赖状态的同步器。它通过一个内部类Sync继承AQS,将同步器所有调用都映射到Sync对应的方法,从而实现了阻塞等待队列、共享/独占、公平/非公平、可重入等行为。

ReentrantLock是JDK中提供的一种基于AQS框架的应用实现,是线程并发访问的同步手段。它具备互斥和同步的功能,同一时刻只允许一个线程访问共享资源,线程之间通过协作实现同步。

二、ReentrantLock的基本使用方式

ReentrantLock提供了公平和非公平锁,以及可重入锁的实现。当前线程如果获取同步状态失败时,AQS会将当前线程已经等待状态等信息构造成一个节点,并将其加入到CLH同步队列,同时会阻塞当前线程。当同步状态释放时,会把首节点唤醒,使其再次尝试获取同步状态。

三、公平和非公平锁的实现

ReentrantLock的公平锁和非公平锁的实现主要是通过lock()和unlock()方法的调用时机来实现的。公平锁会按照线程请求锁的顺序来释放锁,因此公平性更好。而非公平锁则不保证解锁的顺序与锁请求的顺序一致,因此会有一定的竞争。

ReentrantLock是如何实现公平锁和非公平锁的?

ReentrantLock通过AQS框架实现,它提供了公平锁和非公平锁两种锁机制。在实现上,当当前线程获取同步状态失败时,AQS会将当前线程已经等待状态等信息构造成一个节点并将其加入到CLH同步队列中,同时会阻塞当前线程。当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态。

代码示例:

import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock(true); // 创建公平锁实例
    private final ReentrantLock lockNonFair = new ReentrantLock(); // 创建非公平锁实例
    public void method() {
        lock.lock(); // 获取公平锁
        try {
            // 公平锁保护的代码段
        } finally {
            lock.unlock(); // 释放公平锁
        }
        lockNonFair.lock(); // 获取非公平锁
        try {
            // 非公平锁保护的代码段
        } finally {
            lockNonFair.unlock(); // 释放非公平锁
        }
    }
}

Remind:

ReentrantLock类创建了公平锁和非公平锁实例,并在方法中分别使用它们来保护不同的代码段。注意,在使用锁时需要调用lock()方法获取锁,并在finally块中调用unlock()方法释放锁,以确保代码块的正确执行。

四、可重入锁的实现

ReentrantLock的可重入锁是指同一个线程可以多次获取同一个锁,而不会产生死锁。在ReentrantLock中,当一个线程已经获取了锁,再次请求获取该锁时,会返回该线程已经持有的锁,从而实现可重入锁的功能。

代码示例

这段代码中,ReentrantLock构造函数中的true参数表示这是一个可重入锁。当一个线程已经获取了锁,再次调用lock()方法时,会返回这个线程已经持有的锁,从而允许该线程再次获取锁。

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock(true); // true表示可重入锁
    public void doSomething() {
        lock.lock(); // 获取锁
        try {
            // ... 方法体
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}

五、AQS的特性分析

AQS内部维护了一个volatile int state的状态变量,定义了两种资源访问方式:AQS实现时主要实现以下几种方法:Acquire, TryAcquire, Release, HasQueuedThreads, HasWaiters等。AQS定义了5个队列中节点状态:Node、WaitNode、WaitSetNode、SignalNode等。这些队列和节点状态为线程之间的同步提供了基础。

六、总结

ReentrantLock是JDK中基于AQS框架实现的一种独占锁,具备互斥和同步的功能。它的使用方式简单,支持公平和非公平锁,以及可重入锁的实现。AQS是一个抽象同步框架,提供了基础的行为等待队列、条件队列、独占获取、共享获取等,这些行为的抽象为线程之间的同步提供了可能。在设计和实现并发程序时,了解和掌握这些基础知识和工具是非常重要的。

你可能感兴趣的:(lock,java,开发语言,锁)