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 }