前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java项目实践,CountDownLatch实现多线程闭锁

Java项目实践,CountDownLatch实现多线程闭锁

作者头像
用户1289394
发布2021-01-06 00:03:44
5980
发布2021-01-06 00:03:44
举报
文章被收录于专栏:Java学习网Java学习网

摘要

本文主要介绍Java多线程并发中闭锁(Latch)的基本概念、原理、实例代码、应用场景,通过学习,可以掌握多线程并发时闭锁(Latch)的使用方法。

概念

“闭锁”就是指一个被锁住了的门将线程a挡在了门外(等待执行),只有当门打开后(其他线程执行完毕),门上的锁才会被打开,a才能够继续执行。

闭锁(Latch),目的是使多个线程在完成各自任务后,才会打开继续执行后面的任务,否则一直等待。

计数器闭锁(CountDownLatch)是一个同步工具类, 可以用来协调多个线程的执行时间,允许一个或多个线程等待某个事件的发生。

CountDownLatch有个正数的计数器,countDown(); 对计数器做减法操作,await(); 等待计数器等于0。所有await的线程都会阻塞,直到计数器为0或者等待线程中断或者超时。

例如, 可以让a线程在其他线程运行完毕后再执行。如果其他线程没有执行完毕,则a线程就会一直等待。

原理分析

CountDownLatch的实现原理:

1、CountDownLatch在创建时, 会指定一个计数器,表示等待线程的执行数量(比如,3就表示当3个线程执行完毕后,再结束闭锁,使a能够继续执行);

2、 其他每个线程在各自执行完毕时, 分别调用一次countDown())方法,用来递减计数器, 表示有一个线程已经执行完毕了;这时, 线程a可以调用await()方法, 用来等待计数器的值为0。

3、如果计数器的值大于0, 那么await()方法会一直阻塞, 直到计数器为0时,线程a才会继续执行;

4、如果线程a一直无法等到计数器为0,则会显示等待超时,当然也可以在线程a等待时,通过程序中断等待。

实例代码

在Java中, 可以使用CountDownLatch实现多线程闭锁,具体实现代码如下:

代码语言:javascript
复制
package com.javalearns.juc;

import java.util.concurrent.CountDownLatch;

public class JavaLearnsCountDownLatch {
	public static void main(String[] args) {
	    //计数器为8
		CountDownLatch countDownLatch = new CountDownLatch(8);
      //将CountDownLatch对象传递到线程的run()方法中,当每个线程执行完毕run()后就将计数器减1
        MyThread myThread = new MyThread(countDownLatch);
        long start = System.currentTimeMillis();
        //创建8个线程,并执行
		for (int i = 0; i <8; i++) {
			new Thread(myThread).start();
		}
		try {
			//主线程(main)等待:等待的计数器为0;即当CountDownLatch中的计数器为0时,Main线程才会继续执行。
			countDownLatch.await();
		} catch (InterruptedException e) {
		    e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("耗时:" + (end - start));
	}
}
class MyThread implements Runnable {
	private CountDownLatch latch;
	public MyThread(CountDownLatch latch) {
		this.latch = latch;
	}
	@Override
	public void run() {
		try {
			Thread.sleep(5000);
		}catch (InterruptedException e){
		    e.printStackTrace();
        }
            finally {
			latch.countDown();//每个子线程执行完毕后,触发一次countDown(),即计数器减1
		}
	}
}

应用场景

1、确保某个计算,在其需要的所有资源都准备就绪后再执行,比如:要计算某个工程材料的合价,要知道材料的单价和工程量后,才能执行材料合价计算。

2、确保某个服务,在其依赖的所有其他服务都已经启动后再启动。

3、确保某个任务,在所有参与者都准备就绪后再执行,比如:线上上课,在全班30个同学都全部上线后,老师才能开始上课。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java学习网 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档