CountDownLatch的字面意思:倒計時
它的功能是:讓一些線程阻塞直到另外一些線程完成一系列操做後才喚醒。
它經過調用await方法讓線程進入阻塞狀態等待倒計時0時喚醒。
它經過線程調用countDown方法讓倒計時中的計數器減去1,當計數器爲0時,會喚醒哪些由於調用了await而阻塞的線程。多線程
假設老闆開一個緊急會議,他先到會議室等着全部人簽到而後開始開會,可使用CountDownLatch進行模擬。併發
public static void main(String[] args) { CountDownLatch countDownLatch=new CountDownLatch(5); for (int i=1;i<=5;i++){ new Thread(()->{ System.out.println(Thread.currentThread().getName()+"簽到!"); countDownLatch.countDown(); },"第"+i+"個人").start(); } try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("老闆宣佈人夠了開始開會!"); }
運行結果:ui
//注意這裏的簽到順序能夠隨意 第1個人簽到! 第2個人簽到! 第3個人簽到! 第4個人簽到! 第5個人簽到! 老闆宣佈人夠了開始開會!
CyclicBarrier [ˈsaɪklɪk] [ˈbæriər] 的字面意思:可循環使用的屏障
它的功能是:讓一組線程到達一個屏障時被阻塞,知道最後一個線程到達屏障,全部被屏障攔截的線程纔會繼續執行。
它經過調用await方法讓線程進入屏障,spa
仍是上面的開會的例子,咱們使用CyclicBarrier實現。線程
public static void main(String[] args) { CyclicBarrier cyclicBarrier=new CyclicBarrier(5,()->{ System.out.println("老闆宣佈人夠了開始開會!!"); }); for (int i=1;i<=5;i++){ new Thread(()->{ try { System.out.println(Thread.currentThread().getName()+"簽到!"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },"第"+i+"個人").start(); } }
運行結果:code
第1個人簽到! 第2個人簽到! 第3個人簽到! 第4個人簽到! 第5個人簽到! 老闆宣佈人夠了開始開會!!
Semaphor [ˈseməfɔːr] 信號量的意思;
它主要用於兩個目的:blog
//permits :容許 public Semaphore(int permits) { sync = new NonfairSync(permits); } //還能夠指定是否爲公平鎖 public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); }
假設如今是年終,總經理和副總經理要求全部部分要進行述職彙報工做,這兩個老總爲了提升效率在辦公室裏決定並行聽取工做,使用Semaphor進行模擬。
根據需求咱們能夠肯定共享資源爲兩個老總,併發彙報工做的最多兩個部門。ip
public static void main(String[] args) { Semaphore semaphore=new Semaphore(2); for (int i=1;i<=6;i++){ new Thread(()->{ try { System.out.println(Thread.currentThread().getName()+"到了辦公室門口,等待述職!"); semaphore.acquire(); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }finally { semaphore.release(); System.out.println(Thread.currentThread().getName()+"述職中完畢!"); } },"第"+i+"部門").start(); } }
運行效果:資源
第1部門到了辦公室門口,等待述職! 第2部門到了辦公室門口,等待述職! 第3部門到了辦公室門口,等待述職! 第4部門到了辦公室門口,等待述職! 第6部門到了辦公室門口,等待述職! 第5部門到了辦公室門口,等待述職! 第1部門述職中完畢! 第2部門述職中完畢! 第3部門述職中完畢! 第4部門述職中完畢! 第6部門述職中完畢! 第5部門述職中完畢!
注意結果:第1部門和第2部門是同時進行述職的,是兩兩進行的,也就是說咱們控制了多線程狀況下對共享資源訪問時併發線程的數量。get
CountDownLatch是作減法,CyclicBarrier是作加法,Semaphor的臨界資源能夠反覆使用
CountDownLatch不能重置計數,CycliBarrier提供的reset()方法能夠重置計數,不過只能等到第一個計數結束。Semaphor能夠重複使用。
CountDownLatch和CycliBarrier不能控制併發線程的數量,Semaphor能夠實現控制併發線程的數量。