锁的重入

2023-09-02  本文已影响0人  玖柒叁

什么是可重入

一个线程在执行代码时获取锁之后,如果再继续运行时又遇到同一把锁则能自动获取。

synchronized如何实现可重入

为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1.如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器将会减一。当计数值为0时,这个锁将会被释放。

Lock如何实现可重入

ReentrantLock通过Sync实现锁,而Sync继承了AbstractQueuedSynchronizer。在AbstractQueuedSynchronizer中存在一个state变量,state最初为0说明此时没有线程持有锁,当有线程开始竞争时,他们通过CAS将state修改为1,谁修改成功,谁便获取了锁,并且会将该线程记录到exclusiveOwnerThread中,该变量在AbstractOwnableSynchronizer中,AbstractOwnableSynchronizer是AbstractQueuedSynchronizer的父类。exclusiveOwnerThread变量也帮助实现了可重入,如果当前线程==exclusiveOwnerThread说明当前线程已经持有锁,那么只有增加state的计数即可

final boolean initialTryLock() {
            Thread current = Thread.currentThread();
            if (compareAndSetState(0, 1)) { // first attempt is unguarded
                setExclusiveOwnerThread(current);
                return true;
            } else if (getExclusiveOwnerThread() == current) {
                int c = getState() + 1;
                if (c < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(c);
                return true;
            } else
                return false;
        }
上一篇 下一篇

猜你喜欢

热点阅读