展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

锁(三):ReentrantLock源码之公平锁的实现

  • 公平锁与非公平锁的区别
公平锁:所有线程都老老实实排队 
非公平锁:只要有机会,就先尝试抢占资源 
  • 非公平锁的弊端
可能导致后面排队等待的线程等不到相应的cpu资源,从而引起线程饥饿
  • 源码解析
public class ReentrantLockDemo {

    public static void main(String[] args) {
        // 传入参数true,表示获得公平锁的实现
        ReentrantLock reentrantLock = new ReentrantLock(true);
        reentrantLock.lock();
        reentrantLock.unlock();
    }

}
  • ctrl查看源码
    public void lock() {
        sync.acquire(1);
    }
  • 查看acquire方法
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
  • 查看tryAcquire方法
    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
  • 查看tryAcquire方法的实现
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        @ReservedStackAccess
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();    // 获取当前线程
            int c = getState();      // 获取状态
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }
  • 查看hasQueuedPredecessors方法
    public final boolean hasQueuedPredecessors() {
        Node h, s;
        if ((h = head) != null) {
            if ((s = h.next) == null || s.waitStatus > 0) {
                s = null; // traverse in case of concurrent cancellation
                for (Node p = tail; p != h && p != null; p = p.prev) {
                    if (p.waitStatus <= 0)
                        s = p;
                }
            }
            if (s != null && s.thread != Thread.currentThread())
                return true;
        }
        return false;
    }
  • ctrl + shift + y翻译

  • 继续查看tryAcquire方法的实现

    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;
        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        @ReservedStackAccess
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();    // 获取当前线程
            int c = getState();      // 获取状态
            if (c == 0) {
                if (!hasQueuedPredecessors() &&        // 如果状态为0 ,且如果没有其他线程在等待,就尝试获取锁
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);      // 将当前线程设置成持有锁的线程
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {    // 如果状态>0,即当前线程是持有锁的贤臣
                int nextc = c + acquires;      // 状态加1
                if (nextc < 0)      // 越界时报错
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }
posted @ 2022-05-14 11:53  DogLeftover  阅读(46)  评论(0编辑  收藏  举报