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是可以中斷的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章