CountDownLatch
CountDownLatch类可以设置一个计数器
,然后通过countdown
方法来进行减的操作,使用await
方法等待计数器不大于,然后继续执行await方法之后的语句。
- CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞
- 其他线程调用countDown方法会将计数器减(调用countDown方法的线程不会阻塞)
- 当计数器的值变为0时,因await方法会阻塞的线程会被唤醒,继续执行。
// 演示 CountDownLatch
public class countDownLatchDemo {
// 6个同学离开才能锁门
public static void main(String[] args) throws InterruptedException {
// 创建countdownlatch
CountDownLatch countDownLatch = new CountDownLatch(6);
// 6个同学陆续离开
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"号 离开了教室!");
countDownLatch.countDown();
},String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"锁门走人");
}
}
CyclicBarrier
CyclicBarrier 看英文单词就可以看出大概就是循环阻塞的意思,在使用中CyclicBarrier的构造方法的第一个参数就是目标障碍数,执行CyclicBarrier一次障碍数就会加一,如果达到目标障碍数,才会执行cyclicbarrier.await()之后的语句。
例如:集齐七颗龙珠可以召唤神龙
public class CyclicbarrierDemo {
//创建固定值
private static final int NUMBER = 7;
public static void main(String[] args) {
//创建ciclicbarrier
CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, () -> {
System.out.println("******* 龙珠再现");
});
// 集齐七颗龙珠过程
for (int i = 0; i < 7; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"星龙被收集到了");
//等待
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
},String.valueOf(i)).start();
}
}
}
Semaphore
一个计数的信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire()
,然后再获取该许可。每个release()
添加一个许可,从而可能释放一个正在阻塞的获取值。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行技术,并采取相应的措施。
6辆车停三个停车位
// 6 辆车 三个停车位
public class SemaphoreDemo {
public static void main(String[] args) {
//创建semaphore 设置许可数量
Semaphore semaphore = new Semaphore(3);
// 模拟6辆汽车
for (int i = 0; i < 6; i++) {
new Thread(()->{
//抢占
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"抢到了车位!");
// 设置随机停车时间
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName()+"离开了车位!");
}catch (Exception e){
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}