Замок эквивалентен двери. Прежде чем замок достигнет конечного состояния, дверь всегда закрыта, и ни один поток не может пройти. Когда достигается конечное состояние, дверь откроется и позволит всем потокам пройти. Он может заставить один или несколько потоков ожидать возникновения набора событий. Состояние фиксации состоит из счетчика, инициализируемого формальным положительным числом, указывающим количество ожидаемых событий. Метод countDown уменьшает счетчик, указывая на то, что произошло событие, в то время как метод await ожидает, пока счетчик достигнет 0, что указывает на то, что ожидаемое событие произошло. CountDownLatch подчеркивает, что одному потоку (или нескольким потокам) необходимо дождаться, пока другие n потоков что-то завершат, прежде чем продолжить выполнение.
Сценарий применения:
10 спортсменов готовятся к бегу. Они ждут команды судьи и одновременно начинают бег. Когда последний человек пересекает финишную черту, игра заканчивается. 10 движений эквивалентны 10 потокам. Ключевым моментом здесь является управление 10 потоками для одновременного выполнения и определение момента, когда последний поток достиг конечной точки. Можно использовать две блокировки. Первая блокировка используется для управления 10 потоками, ожидающими приказа судьи, а вторая блокировка контролирует окончание игры.
import java.util.concurrent.CountDownLatch; класс Aworker реализует Runnable {частное int num; частный CountDownLatch end; = начало; this.end = конец; } @Override public void run() { // TODO Автоматически созданная заглушка метода { System.out.println(num + "th люди готовы"); Begin.await(); //Ready} catch (InterruptedException e) { e.printStackTrace(); наконец { end.countDown(); счетчик уменьшается на единицу и достигает конечной точки System.out.println(num + "th люди прибывают" } }} public class Race { public static void main(String[] args) { int num = 10; CountDownLatch начало = новый CountDownLatch (1); CountDownLatch конец = новый CountDownLatch (число); for (int i = 1; я <= num; я ++) {новый поток (новый Aworker (я, начало, конец)).start () ; } try { Thread.sleep((long) (Math.random() * 5000) } catch (InterruptedException e1) { // TODO; Автоматически сгенерированный блок catch e1.printStackTrace(); } System.out.println("судья говорит: беги!"); //Начинаем бег после того, как рефери отдаст команду long startTime = System.nanoTime( ); try { end.await(); //Ожидание конца} catch (InterruptedException e) { // Автоматически создаваемый блок catch e.printStackTrace() }finally { long endTime = System.nanoTime(); System.out.println("судья говорит: все прибыло!"); System.out.println("потратить время: " + (endTime - startTime));
выход
1-й человек готов, 2-й человек готов, 4-й человек готов, 6-й человек готов, 3-й человек готов, 10-й человек готов, 8-й человек готов, 5-й человек готов, 7-й человек готов, 9-й человек готов, судья говорит: бегите! !9-й человек прибыл7-й человек прибыл8-й человек прибыл3-й человек прибыл6-й человек прибылвремя ожидания: 970933