并發(fā)編程之 線程協(xié)作工具 LockSupport

LockSupport

前言

在前面的文章中,我們介紹了并發(fā)工具中的4個,Samephore,CyclicBarrier,CountDownLatch,Exchanger,但是我們漏了一個,非常的好用的工具,樓主在這里必須加上。

LockSupport

LockSupport 是一個非常方便實用的線程阻塞工具,他可以在任意位置讓線程阻塞。并且是靜態(tài)的方法。是不是很心動?

LockSupport 的靜態(tài)方法 park()可以阻塞當(dāng)前線程,類似的還有 parkNanos(),parkUntil()等,他們實現(xiàn)了一個限時的等待。

同樣的,有阻塞的方法,當(dāng)然有喚醒的方法,什么呢?unpark(Thread) 方法。該方法可以將指定線程喚醒。

我們還是來一個例子吧,看看到底有多好用:


public class LockSupportInterruptDemo {

  static Object u = new Object();
  static ChangeObjectThread t1 = new ChangeObjectThread("t1");
  static ChangeObjectThread t2 = new ChangeObjectThread("t2");


  static class ChangeObjectThread extends Thread {

    public ChangeObjectThread(String name) {
      super.setName(name);
    }

    public void run() {
      synchronized (u) {
        System.out.println("in " + getName());
        // wait
        LockSupport.park();
        if (Thread.interrupted()) {
          System.err.println(getName() + "被中斷了");
        }
      }
      System.out.println(getName() + "執(zhí)行結(jié)束了");
    }
  }

  public static void main(String[] args) throws InterruptedException {
    t1.start();
    Thread.sleep(1000);
    t2.start();
    Thread.sleep(3000);

    t1.interrupt();
    // notify
    LockSupport.unpark(t2);
  }

}

執(zhí)行結(jié)果:

完全實現(xiàn)了 wait notify 的功能,但是,請注意,park 方法和 wait 方法相比,不需要獲取某個對象的鎖,也不會拋出 InterruptedException 異常,因此,你需要像我們的例子一樣,使用靜態(tài)方法進(jìn)行判斷。

如果你將 park 方法改成 park(this)/park(Thread),那么在打印 線程dump 信息的時候會打印阻塞對象的詳細(xì)信息。

該方法和 Lock 接口一樣都是使用的 sun.misc.Unsafe 的 park 方法實現(xiàn)的阻塞。

還有一個需要注意的是:park 方法和 unpark 方法執(zhí)行順序不是那么的嚴(yán)格。比如我們在 Thread 類中提到的 suspend 方法 和resume 方法,如果順序錯誤,將導(dǎo)致永遠(yuǎn)無法喚醒,但 park 方法和 unpark 方法則不會,我們測試一下,將 unpark 方法緊跟著 start 方法后面執(zhí)行,那么也就是說,unpark 方法在 線程2 的park 方法之前執(zhí)行,但結(jié)果相同。

我們將 unpark 方法移動到了 start 方法后面,依然正確執(zhí)行。

什么原因呢?這是因為 LockSupport 使用了類似信號量的機(jī)制。他為每一個線程準(zhǔn)備了一個許可(默認(rèn)不可用),如果許可能用,那么 park 函數(shù)會立即返回,并且消費(fèi)這個許可(也就是將許可變?yōu)椴豢捎?/strong>),如果許可不可用,將會阻塞。而 unpark 方法則使得一個許可變?yōu)榭捎?/strong>(但是和信號量不同的是,許可不能累加,你不可能擁有超過要給許可,他永遠(yuǎn)只有一個)。

下面是JDK文檔:

park
unpark

這個特定使得:即使 unpark 方法在 park 方法之前執(zhí)行,他也可以使下一次的 park 操作立即返回。這也使上面的代碼能正確執(zhí)行的原因。

好了,到這里,LockSupport 就介紹完了,可以說,該方法可以替代 wait ,notify ,Condition 的 await ,signal 方法。注意,這里的 park 方法底層和 Lock 的底層實現(xiàn)是一致的。都是掉喲個 sun.misc.Unsafe。這個類可以說很牛逼。

good luck ?。。?!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容