天天看點

鎖(八):ReentrantReadWriteLock之寫鎖源碼實作

  • 檢視案例
public void inCreate() {
        writeLock.lock();
        try {
            i++;
            Thread.sleep(500L);
            j++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            writeLock.unlock();
        }
    }      
  • 檢視lock方法
void lock();      
  • 檢視實作
  • 鎖(八):ReentrantReadWriteLock之寫鎖源碼實作
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方法的實作
  • 鎖(八):ReentrantReadWriteLock之寫鎖源碼實作
@ReservedStackAccess
protected final boolean tryAcquire(int acquires) {
    /*
     * Walkthrough:
     * 1. If read count nonzero or write count nonzero
     *    and owner is a different thread, fail.
     * 2. If count would saturate, fail. (This can only
     *    happen if count is already nonzero.)
     * 3. Otherwise, this thread is eligible for lock if
     *    it is either a reentrant acquire or
     *    queue policy allows it. If so, update state
     *    and set owner.
     */
    Thread current = Thread.currentThread();      // 擷取目前線程、擷取狀态、擷取排他鎖
    int c = getState();
    int w = exclusiveCount(c);
    if (c != 0) {
        // (Note: if c != 0 and w == 0 then shared count != 0)
        if (w == 0 || current != getExclusiveOwnerThread())      // 如果是寫鎖,且目前線程不是持有鎖線程
            return false;
        if (w + exclusiveCount(acquires) > MAX_COUNT)
            throw new Error("Maximum lock count exceeded");
        // Reentrant acquire
        setState(c + acquires);
        return true;
    }
    if (writerShouldBlock() ||
        !compareAndSetState(c, c + acquires))  // 如果是非公平鎖,就傳回false;如果是公平鎖,則等待
        return false;
    setExclusiveOwnerThread(current);
    return true;
}      
  • 檢視釋放鎖
public void inCreate() {
        writeLock.lock();
        try {
            i++;
            Thread.sleep(500L);
            j++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            writeLock.unlock();
        }
    }      
  • 檢視unlock方法
void unlock();      
  • 檢視實作
  • 鎖(八):ReentrantReadWriteLock之寫鎖源碼實作
public void unlock() {
    sync.release(1);
}      
  • 檢視release方法
public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }      
  • 檢視tryRelease方法
protected boolean tryRelease(int arg) {
    throw new UnsupportedOperationException();
}      
  • 檢視實作
@ReservedStackAccess
protected final boolean tryRelease(int releases) {
    if (!isHeldExclusively())      // 判斷持有鎖的線程是否是目前線程,不是則抛出異常
        throw new IllegalMonitorStateException();
    int nextc = getState() - releases;
    boolean free = exclusiveCount(nextc) == 0;      // 排他鎖次數是否為0
    if (free)
        setExclusiveOwnerThread(null);
    setState(nextc);
    return free;
}