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

摘要

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

概念

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

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

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

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

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

9ffc503161c4a5ba35d113eddddb5a91.png

原理分析

CountDownLatch的实现原理:

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

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

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

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

8f0f991342bd3a097431ba3f6f549c23.png

示例代码

在Java中, 可以使用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个同学都全部上线后,老师才能开始上课。

ff668ea1c7956b07f108e1aac46ac8c5.png

我是一名码龄10年的程序员,在这里会分享实在干货,让你少走弯路,成就精彩人生。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值