Javaコンカレント--再読み込みロックReentrantLockの再読み込み方法

2748 ワード

前言
ReentrantLockは、スレッドの再読み込みをサポートするロックです.このロックは、リソースに対するスレッドの重複ロックをサポートできることを示します.synchronizedキーワードステルスのサポートロックの再入力性.synchronizedを使用すると、実行スレッドはロックを取得した後も複数回ロックを取得できます.ReentrantLockは、ロックを完了する再入力性を表示することによって、次にReentrantLockがどのように再入力性を実現するかを検討します.
本文
再入性とは、任意のフィールドがロックを取得した後に再びロックを取得し、ロックによってブロックされないことを意味し、再入性の実現には主に2つの問題を解決する必要がある.
スレッドは再びロックを取得します.ロックは、ロックを取得したスレッドが現在ロックを占有しているスレッドであるかどうかを識別する必要があります.そうであれば、ロックを取得できます.
ロックの最終リリース.スレッドはn回繰り返してロックを取得し、n回目にロックを解除すると、他のスレッドはロックを取得することができる.
スレッド取得ロック
非公平性(デフォルト)実装の場合、スレッドがReentrantLockのlock()メソッドを介してロックを再取得すると、nonfairTryAcquireメソッドが呼び出されて同期状態が取得され、そのメソッドでロックを取得したスレッドが現在ロックを保持しているスレッドであるか否かが判断される.
        final boolean nonfairTryAcquire(int acquires) {
            //       
            final Thread current = Thread.currentThread();
            //       
            int c = getState();
            //      0,         
            if (c == 0) {
                // CAS      
                if (compareAndSetState(0, acquires)) {
                    //              
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //                
            else if (current == getExclusiveOwnerThread()) {
                //               
                int nextc = c + acquires;
                //     
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                //       
                setState(nextc);
                return true;
            }
            return false;
        }

同期ステータスが0であることは、現在ロックを取得するスレッドがないことを示しています.一方、同期状態が0でない場合、現在のスレッドがロックを取得したスレッドであるか否かを判断することによって操作が成功するか否かが決定され、ロックを取得したスレッドが再要求された場合、同期状態の値が増加してtrueに戻り、同期状態が成功したことを示す.
注意:setExclusiveOwnerThread(current)は、独占ロックのスレッド所有者を示すAbstractOwnableSynchronizerのメンバー変数exclusiveOwnerThreadを設定します.
ロック解除
スレッドはReentrantLockのunlock()メソッドによってロックを解放し、tryReleaseメソッドを呼び出して同期状態を解放します.
        protected final boolean tryRelease(int releases) {
            //                 
            int c = getState() - releases;
            //                
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            //                
            boolean free = false;
            if (c == 0) {
                free = true;
                //          
                setExclusiveOwnerThread(null);
            }
            //       
            setState(c);
            return free;
        }

tryReleaseメソッドから、同期状態が0であるかどうかは、ロックが最終的に解放されるかどうかの根拠であり、同期状態が0である場合にのみ、占有スレッドをnullに設定し、trueに戻り、解放に成功したことを示す.