java 多线程-倒计时门栓 CountDownLatch

本文介绍Java并发编程中CountDownLatch的使用方法,通过一个模拟场景解释了如何利用CountDownLatch确保主线程等待子线程完成操作后再继续执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java 倒计时门栓 是指Java的CountDownLatch类;它是Java用于并发编程的辅助类中的其中一个。它的主要功能正如其名称所示:以倒计时为门栓标准。指定线程只有计数为0时,系统才会放开权限让该线程开始执行。CountDownLatch类常用于指定某个工作线程只有等待其他准备线程都准备完(count计数也就变为0)才能开始执行具体的工作任务

public class Test{
	public static void main(String[] arg){
		//定义一个大小为3的 倒计时门栓  用于确认多个线程已经执行完毕 
		//即 countDownLatch.await()之后的代码必须等待countDownLatch.countDown()调用知道countDownLatch大小减少到0
		CountDownLatch countDownLatch = new CountDownLatch(3);
		AtomicInteger num = new AtomicInteger();
		ThreadPoolExecutor pool = new ThreadPoolExecutor(
				3,
				3,
				1000,
				TimeUnit.SECONDS,
				new LinkedBlockingDeque<>(10),new ThreadFactory() {//线程工厂
					@Override
					public Thread newThread(Runnable r) {
						Thread thread = new Thread(Thread.currentThread().getThreadGroup(), r, "test-thread-"+num.getAndIncrement());
						thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
							@Override
							public void uncaughtException(Thread t, Throwable e) {
								System.out.println(t.getName()+"发生了异常:"+e.getMessage());
							}
						});
						return thread;
					}
				},new RejectedExecutionHandler(){//拒绝策略
					@Override
					public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
						throw new RuntimeException("任务呗拒绝,请调整阻塞队列大小");
					}
				});


		//模拟一个场景:王老师想要统计小张、小王、小李三位同学的数学期末考试得分,并计算总分
		//但是这三位同学都忘记了自己的得分,但是可以回家去看看试卷。

		//小张回家后三秒钟,老师知道了小张得到了 98分
		Future<Integer> xiaozhang = pool.submit(()->{
			Thread.sleep(3000);
			countDownLatch.countDown();
			return 93;
		});

		//小王回家后一秒钟,老师知道了小张得到了 98分
		Future<Integer> xiaowang = pool.submit(()->{
			Thread.sleep(1000);
			countDownLatch.countDown();
			return 98;
		});

		//小李回家后五秒钟,老师知道了小张得到了 98分
		Future<Integer> xiaoli = pool.submit(()->{
			Thread.sleep(5000);
			countDownLatch.countDown();
			return 94;
		});

		Runnable laoshi = ()-> {
			try {
				//老师等待三位同学都返回自己的得分后才能继续运行
				countDownLatch.await();
				int total = xiaoli.get()+xiaowang.get()+xiaozhang.get();
				System.out.println(total);
				Thread.sleep(3000);

			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		};

		new Thread(laoshi,"test-thread-teacher").start();//老师统计得分


		if(Thread.activeCount()>1){
			Thread.yield();
		}

		pool.shutdown();
	}
}

注意:CountDownLatch内部通过共享锁实现。在创建CountDownLatch实例时,需要传递一个int型的参数:count,该参数为计数器的初始值,也可以理解为该共享锁可以获取的总次数。当某个线程调用await()方法,程序首先判断count的值是否为0,如果不会0的话则会一直等待直到为0为止。当其他线程调用countDown()方法时,则执行释放共享锁状态,使count值 - 1。当在创建CountDownLatch时初始化的count参数,必须要有count线程调用countDown方法才会使计数器count等于0,锁才会释放,前面等待的线程才会继续运行。注意CountDownLatch不能回滚重置


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值