暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ReentrantLock非公平多次加读锁

小新的专栏 2021-11-20
283
        public static void main(String[] args){
final Printer printer = new Printer();


Thread thread1 = new Thread(){
@Override
public void run() {
try {
                printer.read("test1");
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread1.start();
}
复制
        public void read(String str) throws Exception{
lock.readLock().lock();
lock.readLock().lock();
try {
System.out.println(str);
Thread.sleep(200);
}finally {
lock.readLock().unlock();
}
}
复制
        public void lock() {
sync.acquireShared(1);
}
复制
        public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
复制
        protected final int tryAcquireShared(int unused) {
// thread-0
Thread current = Thread.currentThread();
// c为65536
    int c = getState();
    // 此时没有加读锁, 所以exclusiveCount(c)为0
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return -1;
    // r代表读锁, 加了一次读锁, r=1
int r = sharedCount(c);
if (!readerShouldBlock() &&
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) {
......
}
return fullTryAcquireShared(current);
}
复制
        static final class NonfairSync extends Sync {
......
    final boolean readerShouldBlock() {
return apparentlyFirstQueuedIsExclusive();
}
}      
复制
// 如果某个写线程之前有读线程在队列中,那么先解锁写线程
// 但是目前并没有线程在队列中, head为null, 直接返回false
final boolean apparentlyFirstQueuedIsExclusive() {
Node h, s;
return (h = head) != null &&
(s = h.next) != null &&
!s.isShared() &&
s.thread != null;
}
复制

返回tryAcquireShared方法

protected final int tryAcquireShared(int unused) {
......
if (!readerShouldBlock() &&
r < MAX_COUNT &&
        // state为65536 * 2
compareAndSetState(c, c + SHARED_UNIT)) {
        if (r == 0) {
firstReader = current;
firstReaderHoldCount = 1;
}
        // firstReader为第一次获得锁的线程, 也就是Thread-0 
else if (firstReader == current) {
            // 获得读锁的线程的数量+1
firstReaderHoldCount++;
} else {
......
}
return 1;
}
return fullTryAcquireShared(current);
}
复制
文章转载自小新的专栏,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论