CountDownLatch、CyclicBarrier和Semaphore的作用及使用方法
1.CountDownLatch
- 作用:
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒 - 使用方法:
CountDownLatch主要有两个方法,当一个或多个·线程调用await方法时,调用线程会被阻塞。当计数器的值变为零时,因调用await方法被阻塞得线程会被唤醒,继续执行 - 代码示例:
编写一个模拟关门的方法,线程相当于还在教室中的人,只能人走完才能关门,也就是说锁门的线程在其余线程运行完之前只能等待
public static void closeDoor() throws InterruptedException {
// 已经确定了将要运行完线程的数量,将数量传入CountDownLatch类中
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t已离开教室");
// 每运行一个线程就减一
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
// 当达到以上线程全部运行完时才允许运行以下线程
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t已锁门");
}
- 结果显示:

2.CyclicBarrier
- 作用:
字面意思就是可循环使用的屏障 - 使用方法 ;
它要做的事情是让一组线程到达一个屏障(也可以叫同步点)是被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await方法 - 代码示例:
编写一个模拟集齐钥匙开宝箱的方法每收集到一把钥匙就让这个线程等待,直到收集到五把时才能运行开宝箱的方法,整个线程运行完毕
public static void main(String[] args) {
// 在这个方法里设置的是最终运行条件,而在下面线程进入后要等待,直到设置的线程数量达到参数值才能运行最终条件
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
System.out.println("可以打开宝箱了!!!");
});
for (int i = 0; i < 5; i++) {
new Thread(() -> {
System.out.println("拿到第" + Thread.currentThread().getName() + "把钥匙");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
- 结果显示:

3.Semaphore
- 作用:
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制 - 使用方法:
Semaphore比较上面两个类的好处在于可以复用,通过构造函数设定参数表示固定资源,然后有若干线程去抢夺那些资源。抢夺的时候调用acquire()方法表示已经占用了一份资源,用完后调用release()方法释放掉表示该资源已空闲。相当于是拿到资源加一,释放资源减一,一拿一放实现了复用。 - 代码示例:
模拟一个停车场抢车位的场景:总共4个车位,先到的线程可以先停车,停完两秒之后离开,之后这个车位空缺,又可以有新的车停入
public static void main(String[] args) {
Semaphore semaphore=new Semaphore(4);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"\t已经进入车位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+"\t已经离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放资源
semaphore.release();
}
},String.valueOf(i)).start();
}
}
- 结果显示:
