В этой статье будут представлены основные сведения о CountDownLatch, классе инструмента синхронизации, а также на примерах показано, как использовать этот инструмент.
CountDownLatchjava.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计数减一之后,继续加载其他数据...");
};
Метод запуска выглядит следующим образом: при вызовеhandle()
метод выполняется послеcount.countDown();
,ПозволятьCountDownLatch
Счетчик уменьшается на 1. После уменьшения счетчика на 1 можно продолжать загрузку дополнительных данных, не затрагивая текущий поток
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
counter, а затем выполнить его в методе runcount.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.可以开始游戏...
Адрес исходного кода кейса:GitHub.com/радуга большая/приходите…
Если интересно, нажмите звездочку