使用LockSupport喚醒指定線程

一、wait與notify、notifyAll

開發過程中,對線程阻塞與喚醒我們都知道可以使用object的wait和notify,notifyAll實現。
以上方式的缺點:notify是隨機喚醒某個阻塞的線程,notifyAll喚醒所有阻塞線程,不能實現喚醒指定線程。

二、LockSupport

後來瞭解到LockSupport類,它位於java.util.concurrent.locks,提供了park()與unpark(thread)結合可以實現
操作。

park

阻塞某線程,調用本地方法實現,源碼如下:

    public static void park() {
        unsafe.park(false, 0L);
    }
 public native void park(boolean var1, long var2);

API解釋

park
public static void park(Object blocker)
爲了線程調度,在許可可用之前禁用當前線程。
如果許可可用,則使用該許可,並且該調用立即返回;否則,爲線程調度禁用當前線程,並在發生以下三種情況之一前,使其處於休眠狀態:

其他某個線程調用將當前線程作爲目標調用 unpark;或者
其他某個線程中斷當前線程;或者
該調用不合邏輯地(即毫無理由地)返回。
此方法不 報告是哪個線程導致該方法返回。調用者應該重新檢查最先導致線程暫停的條件。調用者還可以確定返回時該線程的中斷狀態。

unpark(thread)

喚醒指定線程,調用本地方法實現,源碼如下:

    public static void unpark(Thread thread) {
        if (thread != null)
            unsafe.unpark(thread);
    }
  public native void unpark(Object var1);

API解釋

unpark
public static void unpark(Thread thread)
如果給定線程的許可尚不可用,則使其可用。如果線程在 park 上受阻塞,則它將解除其阻塞狀態。否則,保證下一次調用 park 不會受阻塞。如果給定線程尚未啓動,則無法保證此操作有任何效果。
參數:
thread - 要執行 unpark 操作的線程;該參數爲 null 表示此操作沒有任何效果。

三、測試代碼

public class TestPark {

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis() + "TestPark開始測試====");
        System.out.println("該線程線程號爲:" + Thread.currentThread().getName());
        System.out.println(System.currentTimeMillis() + "將該線程實體傳入Test中");
        new Thread(new TestThread(Thread.currentThread())).start();
        System.out.println(System.currentTimeMillis() + "該線程停止====");
        LockSupport.park();
        System.out.println(System.currentTimeMillis() + "線程恢復======");
    }
}
public class TestThread implements Runnable {
    private Thread thread;

    public TestThread() {

    }

    public TestThread(Thread thread) {
        this.thread = thread;
    }

    @Override
    public void run() {
        try {
            System.out.println(System.currentTimeMillis() + "等待開始");
            Thread.sleep(1000);
            System.out.println(System.currentTimeMillis() + "等待結束");
        } catch (Exception e) {
            System.out.println("等待失敗");
        }
        LockSupport.unpark(thread);
        System.out.println("thread:" + thread.getId() + "釋放許可");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章