java多线程系列:CountDownLatch
这篇文章将介绍CountDownLatch这个同步工具类的基本信息以及通过案例来介绍如何使用这个工具。
CountDownLatch是java.util.concurrent包下面的一个工具类,可以用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 它可以允许一个或者多个线程等待其他线程完成操作。

案例
模拟游戏一开始需要加载一些基础数据后才能开始游戏,基础数据加载完可以继续加载其他数据。基础数据包含人物、地图、背景、物品等等。
解决方案
利用CountDownLatch来实现,基础数据加载完毕后,CountDownLatch计数器进行减一操作。当CountDownLatch计数器为0时,表示可以开始游戏。 示意图如下

定义抽象类
定义抽象类AbstractDataRunnable并实现Runnable接口
抽象类包含两个属性
private String name;
private CountDownLatch count;
通过构造函数初始化两个属性
public AbstractDataRunnable(String name, CountDownLatch count) {
this.name = name;
this.count = count;
}
定义方法,提供一个抽象方法handle()供子类去实现,getName()和afterCountDown()提供默认的实现。
public String getName() {
return name;
}
public abstract void handle() throws InterruptedException;
public void afterCountDown(){
System.out.println(this.getName() + ":CountDownLatch计数减一之后,继续加载其他数据...");
};
run方法如下,在调用handle()方法之后执行count.countDown();,让CountDownLatch计数器进行减一操作.计数器减一之后可以继续加载额外的数据,并不影响当前线程
public void run() {
try {
System.out.println(this.getName()+" 开始加载...");
Long l1 = System.currentTimeMillis();
handle();
Long l2 = System.currentTimeMillis();
System.out.println(this.getName()+" 加载完成,花费时间:"+(l2-l1));
} catch (Exception e){
e.printStackTrace();
} finally {
count.countDown();
}
afterCountDown();
}
定义一些数据加载类
背景数据加载类如下,实现了抽象类AbstractDataRunnable的handle()方法,在handle()方法休眠了2秒
public class BackGroundData extends AbstractDataRunnable {
public BackGroundData(String name, CountDownLatch count) {
super(name, count);
}
@Override
public void handle() throws InterruptedException {
//模拟加载时间,2秒
Thread.sleep(2000);
}
}
其他数据加载类代码就不贴出来了,睡眠的时间不同而已
开始游戏
开始游戏类如下,通过构造函数传入CountDownLatch计数器,然后在run方法中执行count.await();方法进行等待基础数据加载完毕。
class StartGame implements Runnable{
private CountDownLatch count;
public StartGame(CountDownLatch count) {
this.count = count;
}
@Override
public void run() {
try {
System.out.println("开始加载基础数据...");
Long l1 = System.currentTimeMillis();
count.await();
Long l2 = System.currentTimeMillis();
System.out.println("基础数据加载完毕,总共花费时长:"+(l2-l1)+".可以开始游戏...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试
public static void main(String[] args) throws IOException {
CountDownLatch count = new CountDownLatch(4);
//主线程
Thread startGameThread = new Thread(new StartGame(count));
startGameThread.start();
//加载数据线程
Thread mapThread = new Thread(new MapData("地图",count));
Thread goodsThread = new Thread(new GoodsData("物品",count));
Thread personageThread = new Thread(new PersonageData("人物",count));
Thread backGroundThread = new Thread(new BackGroundData("背景",count));
mapThread.start();
goodsThread.start();
personageThread.start();
backGroundThread.start();
System.in.read();
}
测试结果内容
开始加载基础数据...
地图 开始加载...
物品 开始加载...
人物 开始加载...
背景 开始加载...
人物 加载完成,花费时间:1000
人物:CountDownLatch计数减一之后,继续加载其他数据...
背景 加载完成,花费时间:2000
背景:CountDownLatch计数减一之后,继续加载其他数据...
物品 加载完成,花费时间:2501
物品:CountDownLatch计数减一之后,继续加载其他数据...
地图 加载完成,花费时间:3001
地图:CountDownLatch计数减一之后,继续加载其他数据...
基础数据加载完毕,总共花费时长:3003.可以开始游戏...
有兴趣的点个Star
java多线程系列:CountDownLatch的更多相关文章
- Java 多线程系列 CountDownLatch
CountDownLatch 一个或多个线程等待其他线程完成操作后在在执行 CountDownLatch通过一个计数器来实现,await方法阻塞直到 countDown() 调用计数器归零之后释放所有 ...
- Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例
概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...
- java多线程系列(八)---CountDownLatch和CyclicBarrie
CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...
- Java多线程系列——计数器 CountDownLatch
简介: CountDownLatch 是一个非常实用的多线程控制工具类,通常用来控制线程的等待,它可以让某个线程等待直到倒计时结束 CountDownLatch 提供了两个主要的方法,await(). ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
- Java多线程系列目录(共43篇)
最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...
- Java多线程系列--“JUC锁”05之 非公平锁
概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...
随机推荐
- Broken Keyboard(模拟数组或者双重链表的运用)
这题我是大写的服气,辛辛苦苦搞了个双重链表结果还一直不对,不对就算了,书上源代码打进去还是不对,我能怎么办我也很无奈.不过这题还是让我对双重链表更加了解和运用了!还是可以的! You’re typin ...
- celery 停止执行中 task
目录 原因 解决过程 原因 因为最近项目需求中需要提供对异步执行任务终止的功能,所以在寻找停止celery task任务的方法.这种需求以前没有碰到过,所以,只能求助于百度和google,但是找遍了资 ...
- 使用Jersey和Jetty开发RESTful Web service
Jersey RESTful 框架是开源的RESTful框架, 实现了JAX-RS (JSR 311 & JSR 339) 规范,是JAX-RS的参考实现,并且提供了更多的特性和工具,简化了R ...
- Spring Boot自定义配置与加载
Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...
- python第三十二天-----算法
算法(Algorithm):一个计算过程,解决问题的方法时间复杂度:用来评估算法运行效率的一个东西ps:在日常使用中,请使用sort(),because no zuo no die! 1.冒泡排序:指 ...
- PostgreSQL 监控磁盘使用
监控磁盘使用 1. 判断磁盘用量 每个表都有一个主要的堆磁盘文件,大多数数据都存储在其中.如果一个表有着可能会很宽(尺寸大)的列, 则另外还有一个TOAST文件与这个表相关联, 它用于存储因为太宽而不 ...
- 【OK210试用体验】进阶篇(2)视频图像采集之MJPG-streamer编译(arm移植)
上一篇([OK210试用体验]进阶篇(1)视频图像采集之MJPG-streamer编译(Ubuntu系统下))进行了MJPG-streamer在Ubuntu下的编译及测试,这一篇针对OK210,进行a ...
- SQL基础(2)
SQL TOP (1)TOP子句 OP 子句用于规定要返回的记录的数目. 对于拥有数千条记录的大型表来说,TOP 子句是非常有用的. 注释:并非所有的数据库系统都支持 TOP 子句. (2)SQL S ...
- python 继承进阶
继承进阶 面向对象 1.类:具有相同属性和方法 的一类事物 类名可以实例化一个对象 类名可以调用类属性,(静态属性 和(方法)动态属性) 2.对象:也就是实例 对象名:调用对象属性 调用方法 3 ...
- 11-24网页基础--Js框架及学习思路
第一部分 基本语法: 1.数据类型(字符串.小数.整数.布尔.时间日期)var s="3.14" var n=parsefloat(s) s+=5;var s="abc3 ...