博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程系列:CountDownLatch
阅读量:6083 次
发布时间:2019-06-20

本文共 3212 字,大约阅读时间需要 10 分钟。

这篇文章将介绍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();}

定义一些数据加载类

背景数据加载类如下,实现了抽象类AbstractDataRunnablehandle()方法,在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

转载地址:http://rzuwa.baihongyu.com/

你可能感兴趣的文章
傻瓜式 Material Design 风格矢量图标生成器
查看>>
Nodejs创建HTTPS服务器
查看>>
ubuntu12.04 安装sublime text 2及插件。
查看>>
AFNetworking、MKNetworkKit和ASIHTTPRequest比较
查看>>
Impala 表使用 Avro 文件格式(翻译)
查看>>
http中返回错误代码的意思
查看>>
Spring – 开发环境 – 手动配置
查看>>
!==和!=有什么区别(js php)
查看>>
python入门神图
查看>>
我的友情链接
查看>>
[一文一命令]ls命令详解
查看>>
EBS FORM 失效工具栏按钮
查看>>
com.sun.jdi.InvocationException occurred invoking method
查看>>
Windows Server 2008 R2 IIS7 搭建PHP环境
查看>>
任务计划
查看>>
交换机杂记
查看>>
shell编程总结
查看>>
我的友情链接
查看>>
Java内存与垃圾回收调优
查看>>
Java 8新特性:Stream API
查看>>