CountDownLatch類計數器的使用
主要有兩個方法,當一個或者多個線程調用await()方法時,調用的線程會被阻塞,其它線程調用countDown()方法時將計數器減去1(調用countDown()方法的線程不會被阻塞),但計數器的值變為0時,因為調用await()方法被阻塞的線程會被喚醒,繼續執行。
代碼舉例:

1 package com.countdownlatch; 2 3 import java.util.concurrent.CountDownLatch; 4 5 /** 6 * CountDownLatch 類計數器的使用 7 * CountDownLatch 主要有兩個方法,當一個或者多個線程調用await()方法時,調用線程會被阻塞, 8 * 其它線程調用countDown()方法將計數器減 1 (調用countdown()方法的線程不會被阻塞), 9 * 但計數器的值變為零時,因調用await()方法被阻塞的線程會被喚醒,繼續執行。 10 */ 11 public class CountDownLatchDemo { 12 public static void main(String[] args) throws InterruptedException { 13 CountDownLatch count = new CountDownLatch(6); 14 for (int i = 1; i <= 6; i++) { 15 new Thread(() -> { 16 System.out.println(Thread.currentThread().getName() + "\t 國,被滅"); 17 count.countDown();//逐個減一,只有所有的線程執行完成,才會執行下面的代碼(倒計數 ) 18 }, CountDownLatchEnum.getMessenger(i).getRetMessenger()).start(); 19 } 20 count.await();//判斷上面的線程是否執行完成,若未完成;則返回上面繼續執行,直到上面的線程執行完成,才會執行下面的代碼 21 System.out.println(Thread.currentThread().getName().replaceAll("main","秦") + "\t 國,統一六國"); 22 } 23 }
枚舉輔助類:

1 package com.countdownlatch; 2 3 4 /** 5 * CountDownLatch 的枚舉輔助類 6 */ 7 public enum CountDownLatchEnum { 8 ONE(1, "齊"), TWO(2, "楚"), THREE(3, "燕"), FORE(4, "韓"), FINE(5, "趙"), SIT(6, "魏"); 9 private int retCode; 10 private String retMessenger; 11 12 public int getRetCode() { 13 return retCode; 14 } 15 16 public String getRetMessenger() { 17 return retMessenger; 18 } 19 20 CountDownLatchEnum(int retCode, String retMessenger) { 21 this.retCode = retCode; 22 this.retMessenger = retMessenger; 23 } 24 25 public static CountDownLatchEnum getMessenger(int index) { 26 CountDownLatchEnum[] elemts = CountDownLatchEnum.values(); 27 for (CountDownLatchEnum iter : elemts) { 28 if (iter.getRetCode() == index) { 29 return iter; 30 } 31 } 32 return null; 33 } 34 }
CyclicBarrier類型的用法正好和CountDownLatch意思相反
等所有線程都收集完成,才會執行下一個方法;比如:7個人會議,只有7個人全部到齊了才可以開會,否則只能等着。
代碼舉例:

1 package com.countdownlatch; 2 3 import java.util.concurrent.BrokenBarrierException; 4 import java.util.concurrent.CyclicBarrier; 5 6 /** 7 * CyclicBarrier 等所有的線程都收集完成,才會執行下一個方法;比如:7個人會議;只有7個人 8 * 全部到齊了才可以開會;否則只能等着。 9 */ 10 public class CyclicBarrierDemo { 11 public static void main(String[] args) { 12 CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> { 13 System.out.println("人員到齊,會議開始...."); 14 }); 15 for (int i = 1; i <= 7; i++) { 16 new Thread(() -> { 17 System.out.println(Thread.currentThread().getName() + "\t 簽到..."); 18 try { 19 cyclicBarrier.await(); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } catch (BrokenBarrierException e) { 23 e.printStackTrace(); 24 } 25 }, CyclicBarrierEnum.getMessenger(i).getRetMessenger()).start(); 26 } 27 } 28 }
枚舉輔助類:

1 package com.countdownlatch; 2 3 4 /** 5 * CyclicBarrier 的枚舉輔助類 6 */ 7 public enum CyclicBarrierEnum { 8 ONE(1, "班長"), TWO(2, "副班長"), THREE(3, "學習委員"), FORE(4, "紀律委員"), FINE(5, "生活委員"), SIT(6, "勞動委員"), SERVE(7, "團支書"); 9 private int retCode; 10 private String retMessenger; 11 12 public int getRetCode() { 13 return retCode; 14 } 15 16 public String getRetMessenger() { 17 return retMessenger; 18 } 19 20 CyclicBarrierEnum(int retCode, String retMessenger) { 21 this.retCode = retCode; 22 this.retMessenger = retMessenger; 23 } 24 25 public static CyclicBarrierEnum getMessenger(int index) { 26 CyclicBarrierEnum[] elemts = CyclicBarrierEnum.values(); 27 for (CyclicBarrierEnum iter : elemts) { 28 if (iter.getRetCode() == index) { 29 return iter; 30 } 31 } 32 return null; 33 } 34 }
SemapJore 信號量(燈)
主要有兩個目的:1、多個共享資源的互斥使用
2、用於並發線程數的控制
代碼舉例:

1 package com.countdownlatch; 2 3 import java.util.concurrent.Semaphore; 4 import java.util.concurrent.TimeUnit; 5 6 /** 7 * Semaphore 信號量(燈)主要用於兩個目的:一是多個共享資源的互斥使用,另一個用於並發線程數的控制 8 * <p> 9 * 比如:爭車位,開走一輛,進入一輛,沒位置的只能等着,只要有其它車輛開走,立馬搶空車位。 10 */ 11 public class SemaphoreDemo { 12 public static void main(String[] args) { 13 //模擬 3 個停車位 14 Semaphore semaphore = new Semaphore(3); 15 for (int i = 1; i <= 6; i++) {//6輛車去搶三個車位 16 new Thread(() -> { 17 try { 18 semaphore.acquire();//搶到車位,停車場的空位減 1 19 System.out.println(Thread.currentThread().getName() + "\t 搶到車位"); 20 try { 21 TimeUnit.SECONDS.sleep(3); 22 } catch (InterruptedException e) { 23 e.printStackTrace(); 24 }//停3 秒后離開停車場 25 System.out.println(Thread.currentThread().getName() + "\t 停車3秒后,離開停車場"); 26 } catch (InterruptedException e) { 27 e.printStackTrace(); 28 } finally { 29 semaphore.release();//離開停車場,釋放停車場的位置;讓其它車輛爭搶位置 30 } 31 }, String.valueOf(i)).start(); 32 } 33 34 } 35 }