0
点赞
收藏
分享

微信扫一扫

JUC之CountDownLatch

時小白 2022-03-30 阅读 39
java

JUC之CountDownLatch

1.简介

countDownLatch是在java1.5被引入的,是java.util.current包下的一个类,简称JUC线程工具类(另外三个类后续介绍),使一个线程等待其他线程各自执行完毕后再执行。

2.原理

内部是通过一个计数器(抽象类AbstractQueuedSynchronizer有个int类型的state变量即计数器)来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在休眠等待的线程就可以恢复工作了。

3.源码在这里插入图片描述

3.1.构造方法

CountDownLatch(int count)构造一个指定计数的CountDownLatch,count为线程的数量,一旦设置不可修改。当然有的博客说也可以大于线程的数量(暂时还没验证是否会有问题)

3.2.Sync内部类

Sync是CountDownLatch的一个内部类继承AbstractQueuedSynchronizer类简称AQS,后面的await(), countDown()都是通过这个内部类操作AQS这个类。

3.3.await()

比较常用的一个方法,调用此方法的线程进入休眠状态,除非线程被中断。直到计时器为0时,才恢复执行。

3.4.await(long timeout, TimeUnit unit)

await重载的另一个方法,与上述方法区别可以设置超时等待时间,这个方法我没用过,感觉不太常用。(后面用到的话在进行补充)

3.2.countDown()

如果计数器到达零,则释放所有等待的线程。如果当前计数大于零,则将计数-1。

3.2.getCount()

获取计时器当前的数值,就上述的那个state的值。

4.基本使用demo

4.1场景:双十一秒杀活动,这个活动可以理解为主线程,小明、张三、李四三个人分别为子线程,都准备抢购了。代码如下:
public static void main(String[] args) {
		CountDownLatch latch = new CountDownLatch(1);
		for (int i = 0; i < 5; i++) {
			new Thread(new Runnable() {
				public void run() {
					try {
						//当前线程阻塞
						latch.await();
						//多线程中随机数
						Thread.sleep(3000+ThreadLocalRandom.current().nextInt(1000));
						System.out.println("线程"+Thread.currentThread().getName() + "抢到了!");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
		try {
			Thread.sleep(5000L);
			//所有线程恢复运行
			latch.countDown();
			System.out.println("5s后秒杀活动开始...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

运行结果如下:

在这里插入图片描述

4.2场景:学校准备考试,监考老师肯定要收完所有卷子才会离开。代码如下:
public static void main(String[] args) {
		int size = 5;
		CountDownLatch latch = new CountDownLatch(size);
		for (int i = 0; i < 5; i++) {
			new Thread(new Runnable() {
				public void run() {
					try {
						Thread.sleep(2000+ThreadLocalRandom.current().nextInt(1000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程"+Thread.currentThread().getName() + "同学卷子交了!");
					latch.countDown();
				}
			}).start();
		}
		try {
			latch.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("所有人都交齐了,监考老师离开教室!");
	}

在这里插入图片描述

举报

相关推荐

0 条评论