java高併發實戰程式設計(二)
一:倒計時器:countDownLatch
countDownLatch是一個實用的多執行緒控制工具類。又稱為倒計時器,通常用來控制執行緒等待,可以讓某一個執行緒等待直到倒計時結束,再開始執行。
解釋:也就是一個任務在開始之前要等待一系列準備條件完成時,然後再開始執行,如火箭發射要進行各種儀器檢查無誤之後才能進行發射操作,而這個等待過程就是倒計時器的操作原理。
解析:countDown()用於通知countDownLatch,一個執行緒已經完成了任務,倒計時器可以減一了。方法countDownLatch.await();要求主執行緒等待所有10個檢查任務全部完成,只有任務都完成了,主執行緒才繼續執行。
二:迴圈柵欄:CyclicBarrier
CyclicBarrier 是另外一種多執行緒併發控制實用工具。和CountDownLatch累死,也可以實現執行緒間的計數等待,比countDownLatch更加複雜強大。
柵欄是一種障礙物,這裡用來阻止執行緒繼續執行,要求執行緒在柵欄處等待,cyclic為迴圈,可以反覆使用,比如計數器設定為10,湊齊第一批後,計數器會歸零,然後接著湊齊下一批10個執行緒。
一:執行緒阻塞工具類:LockSupport
是一個非常實用的執行緒阻塞工具,可以線上程內任意位置讓執行緒阻塞,和Thread.suspend()相比,彌補了由於resume()在前發生,導致執行緒無法繼續執行的情況。和object.wait()相比,不需要先獲得某個物件的鎖,也不會丟擲InterruptedException異常。
LockSupport的靜態方法 park()可以阻塞當前執行緒,類似還有parkNanos()、parkUntil()等方法,實現了一個限時等待。
程式碼:
public class ThreadUtils { public static Object u = new Object(); static ChangeObjectThread t1 = new ChangeObjectThread("t1"); static ChangeObjectThread t2 = new ChangeObjectThread("t2"); public static class ChangeObjectThread extends Thread{ public ChangeObjectThread(String name){ super.setName(name); } public void run(){ synchronized (u){ System.out.println("in "+getName()); LockSupport.park(); } } } public static void main(String[] args) throws InterruptedException { t1.start(); Thread.sleep(100); t2.start(); LockSupport.unpark(t1); System.out.println("釋放t1"); LockSupport.unpark(t2); t1.join(); t2.join(); } }
使用park()阻塞住了執行緒,只有使用unpark()解除阻塞之後,其他執行緒才能進入。
三:執行緒複用:執行緒池