1、CountDownLatch
 
- 让一些线程阻塞直到另外一些完成后才被唤醒 
  
- CountDownLatch主要有两个方法,当一个或有多个线程调用await方法时,调用的线程会被阻塞.其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞)
 - 当计数器的值变为0,因调用await方法而被阻塞的线程会被唤醒,然后继续执行该线程的操作
 
  
 
package com.song.CountDownLatchTest;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
               System.out.println(Thread.currentThread().getName()+"\t被灭");
               countDownLatch.countDown();
            },CountryEnum.getCountryEnum(i).getMessage()).start();
        }
        countDownLatch.await();
        System.out.println("秦始皇一统天下");
    }
}
 
public enum  CountryEnum {
    ONE(1,"齐国"),TWO(2,"韩国"),THREE(3,"赵国"),FOUR(4,"楚国"),FIVE(5,"燕国"),SIX(6,"魏国");
    private int reCode;
    private String message;
    CountryEnum(int reCode, String message) {
        this.reCode = reCode;
        this.message = message;
    }
    public static CountryEnum getCountryEnum(int i){
        CountryEnum[] values = CountryEnum.values();
        for (CountryEnum countryEnum : values) {
            if (countryEnum.getReCode() == i) {
                return countryEnum;
            }
        }
        return null;
    }
   
    public int getReCode() {
        return reCode;
    }
    public void setReCode(int reCode) {
        this.reCode = reCode;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
 
###输出随机结果
齐国	被灭
燕国	被灭
魏国	被灭
楚国	被灭
韩国	被灭
赵国	被灭
秦始皇一统天下
Process finished with exit code 0
 
2、CyclicBarrier
 
- CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(barrier) 
  
- 它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法.
 
  
 
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        
        CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
            System.out.println("召唤神龙");
        });
        
        for (int i = 1; i <=7; i++) {
            final int temp = i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"\t 收集到第"+ temp +"颗龙珠");
                try {
                    
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
 
###输出的随机结果
3	 收集到第3颗龙珠
5	 收集到第5颗龙珠
1	 收集到第1颗龙珠
2	 收集到第2颗龙珠
6	 收集到第6颗龙珠
4	 收集到第4颗龙珠
7	 收集到第7颗龙珠
召唤神龙
Process finished with exit code 0
 
3、Semaphore
 
- 是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore(信号量)的主要两个目的,一个是用于多个共享资源的相互排斥使用,另一个用于并发资源数的控制.
 
 
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t 号车抢到了停车位");
                    try { 
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) { 
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"\t 号车停了三秒走了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}
 
###输出的随机结果
1	 号车抢到了停车位
3	 号车抢到了停车位
2	 号车抢到了停车位
2	 号车停了三秒走了
3	 号车停了三秒走了
4	 号车抢到了停车位
1	 号车停了三秒走了
5	 号车抢到了停车位
6	 号车抢到了停车位
6	 号车停了三秒走了
4	 号车停了三秒走了
5	 号车停了三秒走了
Process finished with exit code 0