Java ReentrantLock中tryLock與lock的區別(非公平鎖與公平鎖)


設置同步狀態,利用CAS操作。

// CAS操作:如果當前狀態值等於期望值,則自動將同步狀態設置為給定的更新值
protected final boolean compareAndSetState(int expect, int update)

進入tryLock,實際上是非公平鎖的實現(非公平鎖:不能保證正在排隊的線程能拿到鎖,因為可能被新來的線程搶走

public boolean tryLock() {
    return sync.nonfairTryAcquire(1);
}

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 直接更改同步狀態(當前線程直接搶占)
        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;
}

進入lock,實際上是公平鎖的實現(公平鎖:老的線程在排隊,新來的線程也一樣要排隊,不能搶占

public void lock() {
    sync.lock();
}
final void lock() {
    acquire(1);
}
 public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))    // 如果獲取不到鎖,就放進等待隊列(addWaiter),然后阻塞直到成功獲取到鎖
        selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 唯一與非公平鎖不同的是:先判斷等待隊列是否有等待的線程,沒有的話再更改同步狀態。否則返回false。
        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;
}

tryLock和lock不同點

1. tryLock不管拿到拿不到都直接返回;lock如果拿不到則會一直等待。

2. tryLock是可以中斷的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM