這篇文章將介紹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