JUC鎖框架_ ReentrantLock原理分析

上一章詳細(xì)介紹了AQS的源碼粒竖,這一章我們來分析JUC框架中最常用的鎖ReentrantLock(可重入獨占鎖土铺,也叫可重入互斥鎖)

    public class ReentrantLock implements Lock, java.io.Serializable {}

ReentrantLock實現(xiàn)Lock接口,以及Serializable可序列化接口。

可重入獨占鎖的意思:

  1. 同一時間只能有一個線程持有這個鎖。
  2. 持有這個鎖的線程可以再次進(jìn)入另一個被這個鎖鎖住的模塊诈火,即持有這個鎖的線程可以重復(fù)獲取鎖。

一. Lock接口

package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;

public interface Lock {

    // 獲取鎖状答,如果獲取不到冷守,就一直等待刀崖。不響應(yīng)中斷請求
    void lock();

    // 獲取鎖,如果獲取不到教沾,就一直等待蒲跨。如果在線程等待期間有中斷請求就拋出異常
    void lockInterruptibly() throws InterruptedException;

    // 嘗試用非公平鎖方式去獲取鎖译断,立即返回授翻。返回true表示獲取成功,返回false表示獲取失敗
    boolean tryLock();

    // 在規(guī)定的unit時間內(nèi)獲取鎖孙咪,如果時間到了還沒有獲取到鎖堪唐,則返回false,表示獲取失敗
    // 如果在線程等待期間有中斷請求就拋出異常
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    // 當(dāng)前線程釋放占用的鎖翎蹈,并喚醒這個鎖上的一個等待線程
    void unlock();

    // 創(chuàng)建一個Condition對象
    Condition newCondition();
}

這個接口提供獲取鎖淮菠,釋放鎖以及生成Condition對象的方法。

二. 構(gòu)造函數(shù)和成員屬性

2.1 成員屬性

    // ReentrantLock通過sync變量荤堪,實現(xiàn)獨占鎖的操作合陵。
    //Sync是AbstractQueuedSynchronizer的子類
    private final Sync sync;

ReentrantLock只有這一個成員變量,它是AQS的子類澄阳,所以可以通過sync實現(xiàn)獨占鎖的操作拥知。

2.2 構(gòu)造函數(shù)

    // 默認(rèn)創(chuàng)建的是非公平鎖
    public ReentrantLock() {
        sync = new NonfairSync();
    }


    // 根據(jù)fair值,決定創(chuàng)建公平鎖還是非公平鎖
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

根據(jù)參數(shù)fair來決定是公平鎖還是非公平鎖碎赢,默認(rèn)是非公平鎖低剔。

三. Sync內(nèi)部類

這個類也是個抽樣類,它的兩個子類就是FairSync和NonfairSync肮塞。有兩個重要方法襟齿。

3.1 nonfairTryAcquire方法

使用非公平方式去嘗試獲取鎖

    final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // 獲取鎖的記錄狀態(tài)state
            int c = getState();
            // 如果c==0表示當(dāng)前鎖是空閑的
            if (c == 0) {
                // 通過CAS原子操作方式設(shè)置鎖的狀態(tài),如果為true枕赵,表示當(dāng)前線程獲取的鎖猜欺,
                // 為false,鎖的狀態(tài)被其他線程更改拷窜,當(dāng)前線程獲取的鎖失敗
                if (compareAndSetState(0, acquires)) {
                    // 設(shè)置當(dāng)前線程為獨占鎖的線程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 判斷當(dāng)前線程是不是獨占鎖的線程
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                // 更改鎖的記錄狀態(tài)
                setState(nextc);
                return true;
            }
            return false;
        }

方法流程:

  1. 調(diào)用getState方法獲取鎖的記錄狀態(tài)c
  2. 如果c==0表示當(dāng)前鎖是空閑的开皿。因為是非公平的方法獲取鎖,所以直接調(diào)用compareAndSetState更改鎖的狀態(tài)装黑,如果成功副瀑,表示當(dāng)前線程獲取了鎖,如果失敗恋谭,表示鎖的狀態(tài)別的線程更改了糠睡,當(dāng)前線程獲取鎖失敗。
  3. 如果c不等于0疚颊,那么要看當(dāng)前線程是不是獲取鎖的線程狈孔,因為ReentrantLock是可重入鎖信认,獲取鎖的線程可以重復(fù)獲取鎖。

3.2 tryRelease方法

嘗試釋放鎖資源均抽,返回true表示完全釋放了鎖資源嫁赏,返回false表示還持有鎖資源。

因為鎖是可重入的油挥,所以鎖可能要釋放多次潦蝇。

    protected final boolean tryRelease(int releases) {
            // c表示新的鎖的記錄狀態(tài)
            int c = getState() - releases;
            // 如果當(dāng)前線程不是獨占鎖的線程,就拋出IllegalMonitorStateException異常
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            // 標(biāo)志是否可以釋放鎖
            boolean free = false;
            // 當(dāng)新的鎖的記錄狀態(tài)為0時深寥,表示可以釋放鎖
            if (c == 0) {
                free = true;
                // 設(shè)置獨占鎖的線程為null
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

方法流程:

  1. 先計算新的鎖的記錄狀態(tài)c攘乒。
  2. 如果當(dāng)前線程不是獨占鎖的線程,就拋出IllegalMonitorStateException異常惋鹅。
  3. 當(dāng)新的鎖的記錄狀態(tài)為0時则酝,表示完全釋放鎖資源,就喚醒另一個等待鎖的線程了闰集。
  4. 設(shè)置新的鎖的記錄狀態(tài)沽讹。

四. NonfairSync 非公平鎖

    /**
     * 非公平鎖
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        // 獲取鎖,如果沒有獲取到鎖武鲁,則當(dāng)前線程要阻塞等待
        final void lock() {
            // compareAndSetState返回true爽雄,表示當(dāng)前線程獲取鎖成功。
            // 因為是非公平鎖洞坑,所以不需要判斷AbstractQueuedSynchronizer線程等待隊列是否有值
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                // 調(diào)用acquire方法盲链,獲取鎖
                acquire(1);
        }

        // 嘗試獲取鎖,獲取到鎖返回true迟杂,沒有獲取到返回false
        protected final boolean tryAcquire(int acquires) {
            // 調(diào)用父類的nonfairTryAcquire方法
            return nonfairTryAcquire(acquires);
        }
    }

繼承Sync類需要復(fù)寫兩個方法:

  1. lock獲取鎖的方法刽沾。 因為是非公平鎖方式獲取鎖,所以先直接調(diào)用compareAndSetState方法排拷,如果返回true侧漓,表示鎖資源被當(dāng)前線程持有了。返回false表示鎖的狀態(tài)state不是0监氢,鎖資源已經(jīng)被持有了布蔗。則調(diào)用acquire方法,再次獲取鎖浪腐,不成功就阻塞當(dāng)前線程纵揍。
  2. tryAcquire方法:嘗試獲取鎖,獲取到鎖返回true议街,沒有獲取到返回false泽谨。這里調(diào)用父類的nonfairTryAcquire方法

五. FairSync 公平鎖

    /**
     * 公平鎖
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            // 與非公平鎖不同,因為它要考慮線程等待隊列是否有值
            acquire(1);
        }

        // 嘗試獲取鎖,與與非公平鎖最大的不同就是調(diào)用hasQueuedPredecessors()方法
        // hasQueuedPredecessors方法返回true吧雹,表示等待線程隊列中有一個線程在當(dāng)前線程之前骨杂,
        // 根據(jù)公平鎖的規(guī)則,當(dāng)前線程不能獲取鎖雄卷。
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // 獲取鎖的記錄狀態(tài)
            int c = getState();
            // 如果c==0表示當(dāng)前鎖是空閑的
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 判斷當(dāng)前線程是不是獨占鎖的線程
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                // 更改鎖的記錄狀態(tài)
                setState(nextc);
                return true;
            }
            return false;
        }
    }
  1. lock 方法:與非公平鎖相比搓蚪,它直接調(diào)用acquire方法,因為是公平鎖丁鹉,所以必須考慮當(dāng)前線程是不是CLH隊列中第一個(即隊列中第一個等待線程)

  2. tryAcquire 方法:與非公平鎖相比妒潭,會調(diào)用調(diào)用hasQueuedPredecessors()方法。 hasQueuedPredecessors方法返回true鳄炉,表示等待線程隊列中有一個線程在當(dāng)前線程之前杜耙,根據(jù)公平鎖的規(guī)則搜骡,當(dāng)前線程不能獲取鎖拂盯。

示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {

    public static void newThread(Lock lock, String name, int time) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("線程"+Thread.currentThread().getName()+" 開始運行,準(zhǔn)備獲取鎖");
                lock.lock();
                try {
                    System.out.println("====線程"+Thread.currentThread().getName()+" 在run方法中獲取了鎖");
                    lockAgain();
                    try {
                        Thread.sleep(time);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    System.out.println("----線程"+Thread.currentThread().getName()+" 在run方法中釋放了鎖");
                    lock.unlock();
                }
            }

            private void lockAgain() {
                lock.lock();
                try {
                    System.out.println("====線程"+Thread.currentThread().getName()+"  在lockAgain方法中再次獲取了鎖");
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } finally {
                    System.out.println("----線程"+Thread.currentThread().getName()+" 在lockAgain方法中釋放了鎖");
                    lock.unlock();
                }
            }
        },name).start();
    }

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        newThread(lock, "t1111", 1000);
        newThread(lock, "t2222", 1000);
        newThread(lock, "t3333", 1000);
    }
}

從這個例子中可以看出ReentrantLock是一個可重入鎖记靡,當(dāng)前持有鎖的線程可以進(jìn)入另一個被鎖住的模塊谈竿,而且只有都釋放完成之后,它才會去喚醒一個等待鎖的線程摸吠。

注意一個有趣點空凸,雖然我們創(chuàng)建的非公平鎖,但是每次釋放鎖完成后寸痢,去喚醒一個等待線程時呀洲,你會發(fā)現(xiàn)它一定是等待線程中的第一個線程。那么不是和非公平鎖定義好像不一樣啊啼止。
其實非公平鎖和公平鎖最大的區(qū)別是道逗,當(dāng)鎖是空閑的即沒有任何線程持有鎖,非公平鎖就允許當(dāng)前線程直接獲取鎖献烦,而不用考慮是否有其他線程已經(jīng)在等待這把鎖了滓窍。而公平鎖不是這樣,如果有等待線程隊列巩那,那么就將當(dāng)前線程插入到等待線程隊列尾吏夯。

輸出結(jié)果是

線程t1111 開始運行,準(zhǔn)備獲取鎖
====線程t1111 在run方法中獲取了鎖
====線程t1111  在lockAgain方法中再次獲取了鎖
線程t2222 開始運行即横,準(zhǔn)備獲取鎖
線程t3333 開始運行噪生,準(zhǔn)備獲取鎖
----線程t1111 在lockAgain方法中釋放了鎖
----線程t1111 在run方法中釋放了鎖
====線程t2222 在run方法中獲取了鎖
====線程t2222  在lockAgain方法中再次獲取了鎖
----線程t2222 在lockAgain方法中釋放了鎖
----線程t2222 在run方法中釋放了鎖
====線程t3333 在run方法中獲取了鎖
====線程t3333  在lockAgain方法中再次獲取了鎖
----線程t3333 在lockAgain方法中釋放了鎖
----線程t3333 在run方法中釋放了鎖
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class WaitTest {
    private Lock lock;
    private Condition condition;

    public WaitTest() {
        this.lock = new ReentrantLock();
        this.condition = this.lock.newCondition();
    }

    public void waitTest() {
        lock.lock();
        try {
            System.out.println("===線程"+Thread.currentThread().getName()+" 獲取了鎖");
            try {
                Thread.sleep(1000);
                System.out.println("========線程"+Thread.currentThread().getName()+"  調(diào)用await方法 等待并釋放了鎖");
                this.condition.await();
                System.out.println("========線程"+Thread.currentThread().getName()+"  await等待被喚醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } finally {
            System.out.println("---線程"+Thread.currentThread().getName()+"  釋放鎖");
            lock.unlock();
        }
    }

    public void signalTest() {
        lock.lock();
        try {
            System.out.println("===線程"+Thread.currentThread().getName()+"  獲取了鎖");
            System.out.println("-------線程"+Thread.currentThread().getName()+"  調(diào)用signal方法");
            this.condition.signal();
        } finally {
            System.out.println("---線程"+Thread.currentThread().getName()+"  釋放鎖");
            lock.unlock();
        }
    }

}

public class LockWaitTest {

    public static void newThread(WaitTest waitTest, String name, boolean isWait) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (isWait) waitTest.waitTest();
                else waitTest.signalTest();
            }
        },name).start();
    }

    public static void main(String[] args) {
        WaitTest waitTest = new WaitTest();
        newThread(waitTest, "t1111", true);
        newThread(waitTest, "t2222", false);
//        newThread(waitTest, "t3333", true);
//        newThread(waitTest, "t4444", false);
    }
}

輸出結(jié)果是

===線程t1111 獲取了鎖
========線程t1111  調(diào)用await方法 等待并釋放了鎖
===線程t2222  獲取了鎖
-------線程t2222  調(diào)用signal方法
---線程t2222  釋放鎖
========線程t1111  await等待被喚醒
---線程t1111  釋放鎖

附錄

    package java.util.concurrent.locks;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    // ReentrantLock通過sync屬性,實現(xiàn)獨占鎖的操作东囚。
    // Sync是AbstractQueuedSynchronizer的子類
    private final Sync sync;


    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;


        // 加鎖操作跺嗽,又子類具體實現(xiàn)
        abstract void lock();


        // 非公平狀態(tài)下獲取鎖
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // 獲取鎖的記錄狀態(tài)state
            int c = getState();
            // 如果c==0表示當(dāng)前鎖是空閑的
            if (c == 0) {
                // 通過CAS原子操作方式設(shè)置鎖的狀態(tài),如果為true,表示當(dāng)前線程獲取的鎖抛蚁,
                // 為false陈醒,鎖的狀態(tài)被其他線程更改,當(dāng)前線程獲取的鎖失敗
                if (compareAndSetState(0, acquires)) {
                    // 設(shè)置當(dāng)前線程為獨占鎖的線程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 判斷當(dāng)前線程是不是獨占鎖的線程
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                // 更改鎖的記錄狀態(tài)
                setState(nextc);
                return true;
            }
            return false;
        }

        protected final boolean tryRelease(int releases) {
            // c表示新的鎖的記錄狀態(tài)
            int c = getState() - releases;
            // 如果當(dāng)前線程不是獨占鎖的線程瞧甩,就拋出IllegalMonitorStateException異常
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            // 標(biāo)志是否可以釋放鎖
            boolean free = false;
            // 當(dāng)新的鎖的記錄狀態(tài)為0時钉跷,表示可以釋放鎖
            if (c == 0) {
                free = true;
                // 設(shè)置獨占鎖的線程為null
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

        protected final boolean isHeldExclusively() {
            // 返回當(dāng)前線程是不是獨占鎖的線程
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

        final ConditionObject newCondition() {
            return new ConditionObject();
        }

        final Thread getOwner() {
            // 返回獨占鎖的線程
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }

        final int getHoldCount() {
            // 只有當(dāng)前線程是獨占鎖的線程,才會返回鎖的記錄狀態(tài)state肚逸,否則返回0
            return isHeldExclusively() ? getState() : 0;
        }

        final boolean isLocked() {
            // 返回鎖是不是被使用狀態(tài)
            return getState() != 0;
        }

        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }
    }

    /**
     * 非公平鎖
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        // 獲取鎖爷辙,如果沒有獲取到鎖,則當(dāng)前線程要阻塞等待
        final void lock() {
            // compareAndSetState返回true朦促,表示當(dāng)前線程獲取鎖成功膝晾。
            // 因為是非公平鎖,所以不需要判斷AbstractQueuedSynchronizer線程等待隊列是否有值
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                // 調(diào)用acquire方法务冕,獲取鎖
                acquire(1);
        }

        // 嘗試獲取鎖血当,獲取到鎖返回true,沒有獲取到返回false
        protected final boolean tryAcquire(int acquires) {
            // 調(diào)用父類的nonfairTryAcquire方法
            return nonfairTryAcquire(acquires);
        }
    }

    /**
     * 公平鎖
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            // 與非公平鎖不同禀忆,因為它要考慮線程等待隊列是否有值
            acquire(1);
        }

        // 嘗試獲取鎖臊旭,與與非公平鎖最大的不同就是調(diào)用hasQueuedPredecessors()方法
        // hasQueuedPredecessors方法返回true,表示等待線程隊列中有一個線程在當(dāng)前線程之前箩退,
        // 根據(jù)公平鎖的規(guī)則离熏,當(dāng)前線程不能獲取鎖。
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // 獲取鎖的記錄狀態(tài)
            int c = getState();
            // 如果c==0表示當(dāng)前鎖是空閑的
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 判斷當(dāng)前線程是不是獨占鎖的線程
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                // 更改鎖的記錄狀態(tài)
                setState(nextc);
                return true;
            }
            return false;
        }
    }


    // 默認(rèn)創(chuàng)建的是非公平鎖
    public ReentrantLock() {
        sync = new NonfairSync();
    }


    // 根據(jù)fair值戴涝,決定創(chuàng)建公平鎖還是非公平鎖
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

    // 獲取鎖滋戳,如果獲取不到,就一直等待啥刻。不響應(yīng)中斷請求
    public void lock() {
        sync.lock();
    }

    // 獲取鎖奸鸯,如果獲取不到,就一直等待郑什。如果有中斷請求就拋出異常
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    // 嘗試用非公平鎖方式去獲取鎖府喳,立即返回。返回true表示獲取成功蘑拯,返回false表示獲取失敗
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }

    // 在規(guī)定的unit時間內(nèi)獲取鎖钝满,如果時間到了還沒有獲取到鎖,則返回false申窘,表示獲取失敗
    // 如果在線程等待期間有中斷請求就拋出異常
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

    // 當(dāng)前線程釋放占用的鎖弯蚜,并喚醒這個鎖上的一個等待線程
    public void unlock() {
        sync.release(1);
    }

    // 創(chuàng)建一個Condition對象
    public Condition newCondition() {
        return sync.newCondition();
    }

    //
    public int getHoldCount() {
        return sync.getHoldCount();
    }

    // 當(dāng)前線程是不是持有鎖的線程
    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }

    // 鎖是否已經(jīng)被持有
    public boolean isLocked() {
        return sync.isLocked();
    }

    // 是不是公平鎖
    public final boolean isFair() {
        return sync instanceof FairSync;
    }

    // 返回持有鎖的線程,如果null剃法,表示沒有任何線程持有鎖
    protected Thread getOwner() {
        return sync.getOwner();
    }

    // 是不是有等待鎖的線程碎捺,即鎖的同步隊列是不是不為空
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    // 等待鎖的線程隊列中有沒有thread線程
    public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }

    // 等待鎖線程隊列的長度
    public final int getQueueLength() {
        return sync.getQueueLength();
    }

    // 返回等到鎖的線程隊列的集合
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }

    // condition對象的condition隊列是否有等待線程
    public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    // condition對象上等待線程的個數(shù)
    public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    // condition對象上等待線程的集合
    protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    public String toString() {
        Thread o = sync.getOwner();
        return super.toString() + ((o == null) ?
                                   "[Unlocked]" :
                                   "[Locked by thread " + o.getName() + "]");
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子收厨,更是在濱河造成了極大的恐慌晋柱,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诵叁,死亡現(xiàn)場離奇詭異雁竞,居然都是意外死亡,警方通過查閱死者的電腦和手機拧额,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門碑诉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侥锦,你說我怎么就攤上這事进栽。” “怎么了恭垦?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵快毛,是天一觀的道長。 經(jīng)常有香客問我署照,道長祸泪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任建芙,我火速辦了婚禮,結(jié)果婚禮上懂扼,老公的妹妹穿的比我還像新娘禁荸。我一直安慰自己,他們只是感情好阀湿,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布赶熟。 她就那樣靜靜地躺著,像睡著了一般陷嘴。 火紅的嫁衣襯著肌膚如雪映砖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天灾挨,我揣著相機與錄音邑退,去河邊找鬼。 笑死劳澄,一個胖子當(dāng)著我的面吹牛地技,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秒拔,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼莫矗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起作谚,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤三娩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后妹懒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尽棕,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年彬伦,在試婚紗的時候發(fā)現(xiàn)自己被綠了滔悉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡单绑,死狀恐怖回官,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搂橙,我是刑警寧澤歉提,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站区转,受9級特大地震影響苔巨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜废离,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一侄泽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜻韭,春花似錦悼尾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至俯画,卻和暖如春析桥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艰垂。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工泡仗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人材泄。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓沮焕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拉宗。 傳聞我的和親對象是個殘疾皇子峦树,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容