这篇文章将介绍CountDownLatch这个同步工具类的基本信息以及经过案例来介绍如何使用这个工具。java
CountDownLatch是java.util.concurrent
包下面的一个工具类,能够用来协调多个线程之间的同步,或者提及到线程之间的通讯(而不是用做互斥的做用)。 它能够容许一个或者多个线程等待其余线程完成操做。
git
模拟游戏一开始须要加载一些基础数据后才能开始游戏,基础数据加载完能够继续加载其余数据。基础数据包含人物、地图、背景、物品等等。github
利用CountDownLatch
来实现,基础数据加载完毕后,CountDownLatch
计数器进行减一操做。当CountDownLatch
计数器为0时,表示能够开始游戏。 示意图以下网络
定义抽象类AbstractDataRunnable
并实现Runnable
接口ide
抽象类包含两个属性函数
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
计数器进行减一操做.计数器减一以后能够继续加载额外的数据,并不影响当前线程this
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