一.CountDownLatch—计数器
代码测试:
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
// 总数是6,必须要等执行完6个线程后才能执行await下面的代码
//例如:有6个学生,一定要等6个学生走完后才能关门
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "Go Out");
countDownLatch.countDown();// 数量-1
}, String.valueOf(i)).start();
}
countDownLatch.await(); // 等待计数器归零,然后再向下执行
System.out.println("关门");
}
}
原理:
countDownLatch.countDown(); // 数量-1
countDownLatch.await(); // 等待计数器归零,然后再向下执行
每次有线程调用 countDown() 数量-1,假设计数器变为0,countDownLatch.await() 就会被唤醒,继续执行!
二.CyclicBarrier—加法计数器
public class CyclicBarrierTest {
public static void main(String[] args) {
/**
* 集齐7颗龙珠召唤神龙
*/
//召唤神龙的过程
CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()-> System.out.println("集齐7颗龙珠,召唤神龙"));
for (int i = 1; i <=7; i++) {
final int temp=i;
new Thread(()-> {
try {
System.out.println(Thread.currentThread().getName()+"收集"+temp+"个龙珠");
cyclicBarrier.await();//等待
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
三.Semaphore----信号量
例如:抢车位问题:6车----3个停车位
public class SemaphoreTest {
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()+"拿到车位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+"离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();// release() 释放
}
}).start();
}
}
}