ReentrantReadWriteLock源码剖析

~码铃薯~ / 2024-09-01 / 原文

ReentrantReadWriteLock源码剖析

测试案例:

public class ReentrantReadWriteLockDemo {

    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private static Lock readLock = readWriteLock.readLock(); // 定义读锁
    private static Lock writeLock = readWriteLock.writeLock(); // 定义写锁
    private int value = 10;

    public static void main(String[] args) {
        new ReadWriteLockDemo().test();
    }

    private void test() {
        for (int j = 0; j < 30; j++) {
            if (j % 5 == 0) {
                new Thread(this::doWrite).start();
            } else {
                new Thread(this::doRead).start();
            }
        }
    }

    // 读取value的值
    private void doRead() {
        try {
            readLock.lock(); // 上读锁
            long timeFlag = System.currentTimeMillis() % 100000;
            System.out.println(timeFlag + " -- " + Thread.currentThread().getName() + " -->> 读取数据 value=" + value);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readLock.unlock(); // 释放读锁
        }
    }

    // 修改value的值
    private void doWrite() {
        try {
            writeLock.lock(); // 添加写锁
            value++;
            long timeFlag = System.currentTimeMillis() % 100000;
            System.out.println(timeFlag + " -- " + Thread.currentThread().getName() + " -->> <<写入>>数据 value=" + value);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock(); // 释放写锁
        }
    }
}

运行结果:

30731 -- Thread-0 -->> <<写入>>数据 value=11
31732 -- Thread-5 -->> <<写入>>数据 value=12
32733 -- Thread-1 -->> 读取数据 value=12
32733 -- Thread-2 -->> 读取数据 value=12
32733 -- Thread-4 -->> 读取数据 value=12
32733 -- Thread-7 -->> 读取数据 value=12
32734 -- Thread-3 -->> 读取数据 value=12
32734 -- Thread-8 -->> 读取数据 value=12
32734 -- Thread-6 -->> 读取数据 value=12
32734 -- Thread-9 -->> 读取数据 value=12
33735 -- Thread-10 -->> <<写入>>数据 value=13
34735 -- Thread-11 -->> 读取数据 value=13
34735 -- Thread-12 -->> 读取数据 value=13
34735 -- Thread-13 -->> 读取数据 value=13
34735 -- Thread-14 -->> 读取数据 value=13
35736 -- Thread-15 -->> <<写入>>数据 value=14
36736 -- Thread-16 -->> 读取数据 value=14
36736 -- Thread-17 -->> 读取数据 value=14
36736 -- Thread-18 -->> 读取数据 value=14
36736 -- Thread-19 -->> 读取数据 value=14
37737 -- Thread-20 -->> <<写入>>数据 value=15
38738 -- Thread-21 -->> 读取数据 value=15
38738 -- Thread-23 -->> 读取数据 value=15
38738 -- Thread-22 -->> 读取数据 value=15
38738 -- Thread-24 -->> 读取数据 value=15
39738 -- Thread-25 -->> <<写入>>数据 value=16
40738 -- Thread-26 -->> 读取数据 value=16
40738 -- Thread-27 -->> 读取数据 value=16
40738 -- Thread-29 -->> 读取数据 value=16
40738 -- Thread-28 -->> 读取数据 value=16

架构图:

image

源码剖析:

public class ReentrantReadWriteLock
        implements ReadWriteLock, java.io.Serializable {
	
    /** Inner class providing readlock 读锁,内部类提供*/
    private final ReentrantReadWriteLock.ReadLock readerLock;
    /** Inner class providing writelock 写锁,内部类提供*/
    private final ReentrantReadWriteLock.WriteLock writerLock;
    
    final Sync sync;// 继承AQS
    
    abstract static class Sync extends AbstractQueuedSynchronizer {
        // 位数
    	static final int SHARED_SHIFT   = 16;
        // 共享⾼16位(读锁标记)
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
        // 读取最⼤数量
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
        // 写锁最⼤数量
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
        
        /** Returns the number of shared holds represented in count 读锁计数 */
        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
        /** Returns the number of exclusive holds represented in count 写锁计数 */
        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
    }
    
    // 非公平锁
    static final class NonfairSync extends Sync {
        // ......
    }
    // 公平锁
    static final class FairSync extends Sync {
        // ......
    }
    
    // 读锁
    public static class ReadLock implements Lock, java.io.Serializable {
    	// ......
    }
    // 写锁    
    public static class WriteLock implements Lock, java.io.Serializable {
    	// ......
    }
    
    public ReentrantReadWriteLock() {
        this(false);
    }
    
    public ReentrantReadWriteLock(boolean fair) {
        // true:公平锁 false:非公平锁
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }

}

加锁:

java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock#lock
可以看到底层走的还是AQS的逻辑

public void lock() {
	sync.acquireShared(1);
}

public final void acquireShared(int arg) {
    if (tryAcquireShared(arg) < 0)
    doAcquireShared(arg);
}

java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock#lock
可以看到底层走的还是AQS的逻辑   
public void lock() {
    sync.acquire(1);
}

public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}

释放锁

java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock#unlock
可以看到底层走的还是AQS的逻辑
public void unlock() {
    sync.releaseShared(1);
}

public final boolean releaseShared(int arg) {
    if (tryReleaseShared(arg)) {
        doReleaseShared();
        return true;
    }
    return false;
}

java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock#unlock
可以看到底层走的还是AQS的逻辑
public void unlock() {
    sync.release(1);
}

public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}

总的来说:ReentrantReadWriteLock底层实现了公平锁、非公平锁、读锁和写锁。