ReentrantLock源码解读

55 阅读1分钟

测试方法

package com.example.hytool.demos.AQS;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {
    private static final ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {

        Runnable task = () -> {
            lock.lock();
            try {
                // 临界区代码
                System.out.println(Thread.currentThread().getName() + " is executing");
                // 模拟耗时操作
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            } finally {
                lock.unlock();
            }
        };

        Runnable task2 = () -> {
            lock.lock();
            try {
                // 临界区代码
                System.out.println(Thread.currentThread().getName() + " is executing");
                // 模拟耗时操作
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            } finally {
                lock.unlock();
            }
        };


        Thread t1 = new Thread(task, "Thread 1");
        Thread t2 = new Thread(task2, "Thread 2");
        Thread t3 = new Thread(task2, "Thread 3");
        Thread t4 = new Thread(task2, "Thread 4");

        t1.start();
        t2.start();
        t3.start();
        t4.start();


    }
}

运行结果 控制台打印

Connected to the target VM, address: '127.0.0.1:50152', transport: 'socket'
Thread 1 is executing
Thread 2 is executing

dump显示 thread 2 被挂起的流程 image.png

非公平 lock方法

通过类图 可以看到 NonfairSync 继承 Sync,Sync继承AQS队列 AbstractQueuedSynchronizer

image.png

image.png


final void lock() {
       //第一次进来 把state的值从0更改为1。cas设置 
    if (compareAndSetState(0, 1))
        //设置当前的独占线程是谁
        setExclusiveOwnerThread(Thread.currentThread());
    else
        
        acquire(1);
}



protected final boolean compareAndSetState(int expect, int update) {
    // See below for intrinsics setup to support this
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}



public final void acquire(int arg) {
     //尝试获取锁,上一次线程可能释放,也可能没释放
     //没释放,锁获取不成功,加入等待队列
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}

protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
}


【java.util.concurrent.locks.ReentrantLock.Sync#nonfairTryAcquire】

//这里尝试获取锁
final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    //为啥这里要判断是否为0,因为上一个线程锁如果释放 会把state值恢复为0
    //相当于又走了第一获取锁的流程
    if (c == 0) {
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    else if (current == getExclusiveOwnerThread()) {
    //这里的代码实现的可重入锁的功能
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    //返回false未获取到锁,进入下一步 加入等待队列
    return false;
}