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
架构图:
源码剖析:
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底层实现了公平锁、非公平锁、读锁和写锁。
标签:读取数据,Thread,ReentrantReadWriteLock,--,value,剖析,源码,public From: https://www.cnblogs.com/dongyaotou/p/18391256