Философия Java3
Шрифт:
Задачи, вызывающие countDown, не блокируются на время вызова. Только вызов await блокируется до момента обнуления счетчика.
Типичный способ применения — разделение задачи на п независимых подзадач и создание объекта CountDownLatch с начальным значением п. При завершении каждая подзадача вызывает countDown для объекта синхронизации. Потоки, ожидающие решения общей задачи, блокируются вызовом await. Описанная методика продемонстрирована в следующем примере:
// concurrency/CountDownLatchDemo java import java.util concurrent.*; import java util *.
import static net mindview util.Print *,
//
class TaskPortion implements Runnable {
private static int counter = 0.
private final int id = counter++;
private static Random rand = new Random(47);
private final CountDownLatch latch;
TaskPortion(CountDownLatch latch) { this latch = latch,
}
public void run { try {
doWorkO;
latch countDownO; } catchdnterruptedException ex) {
// Приемлемый вариант выхода
}
}
public void doWorkO throws InterruptedException {
TimeUnit MILLISECONDS.sleep(rand nextlnt(2000)); pri nt(thi s + "завершается");
}
public String toStringO {
return String.format("^l$-3d ". id),
// Ожидание по объекту CountDownLatch: class WaitingTask implements Runnable { private static int counter = 0; private final int id = counter++; private final CountDownLatch latch, WaitingTask(CountDownLatch latch) { this latch = latch;
public void run { try {
latch awaitO.
printC'Bapbep пройден для " + this); } catchdnterruptedException ex) {
print(this + " interrupted"),
}
}
public String toStringO {
return String format("WaitingTask %l%-36 id).
public class CountDownLatchDemo { static final int SIZE = 100.
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPoolО, // Все подзадачи совместно используют один объект CountDownLatch CountDownLatch latch = new CountDownLatch(SIZE); for(int i = 0; i < 10; i++)
exec.execute(new WaitingTask(1atch)); for(int i = 0; i < SIZE. i++)
exec execute(new TaskPortion(latch)). print("Запущены все задачи"); exec.shutdownO, // Выход по завершению всех задач
}
} /// ~
TaskPortion некоторое время ожидает, имитируя выполнение части задачи, а класс WaitingTask представляет некую часть системы, которая обязана дождаться завершения всех подзадач. Все задачи используют один и тот же объект CountDownLatch, определяемый в main.
CyclicBarrier
Класс CyclicBarrier используется при создании группы параллельно выполняемых задач, завершения которых необходимо дождаться до перехода
Имитации привлекали меня с первых дней работы с компьютерами, и параллельные вычисления играют в них ключевую роль. Даже самая первая программа, которую я написал на BASIC, имитировала скачки на ипподроме. Вот как выглядит объектно-ориентированная, многопоточная версия этой программы с использованием CyclicBarrier:
//: concurrency/HorseRace.java // Using CyclicBarriers import java.util concurrent *; import java.util *;s
import static net.mindview util Print.*;
class Horse implements Runnable { private static int counter = 0; private final int id = counter++; private int strides = 0; private static Random rand = new Random(47); private static CyclicBarrier barrier; public Horse(CyclicBarrier b) { barrier = b; } public synchronized int getStridesO { return strides; } public void run { try {
whi 1 e(!Thread.interruptedO) { synchronized(this) {
strides += rand.nextInt(3); // Produces 0. 1 or 2
}
barrier.awaitO;
}
} catch(InterruptedException e) {
// Приемлемый вариант выхода } catch(BrokenBarrierException e) {
// Исключение, которое нас интересует throw new RuntimeException(e);
}
}
public String toStringO { return "Horse " + id + " "; } public String tracks О {
StringBuilder s = new StringBuilderO; for (int i = 0; i < getStridesO; i++)
s appendC'*"); s.append(id); return s.toStringO;
public class HorseRace {
static final int FINISH_LINE = 75;
private List<Horse> horses = new ArrayList<Horse>0;
private ExecutorService exec =
Executors.newCachedThreadPool ; private CyclicBarrier barrier; public HorseRace(int nHorses. final int pause) {
barrier = new CyclicBarrier(nHorses, new RunnableO { public void runO {
StringBuilder s = new StringBuilderO; for(int i = 0; i < FINISH_LINE; i++)
s.append("="); // Забор на беговой дорожке
print(s);
for(Horse horse ; horses)
print(horse.tracksO); for(Horse horse ; horses)
if (horse. getStridesO >= FINISH_LINE) { print(horse + "won!"); exec.shutdownNowO; return;
}
try {
Ti meUnit.MILLISECONDS.s1eep(pause); } catch(InterruptedException e) {
printC'barrier-action sleep interrupted");
}
}).
for(int i = 0. i < nHorses; i++) {
Horse horse = new Horse(barrier); horses add(horse); exec.execute(horse);
70 Рублей
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
рейтинг книги
Переписка 1826-1837
Документальная литература:
публицистика
рейтинг книги

Морской волк. 1-я Трилогия
1. Морской волк
Фантастика:
альтернативная история
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель
Фантастика:
фэнтези
героическая фантастика
рейтинг книги
Честное пионерское! Часть 4
4. Честное пионерское!
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Здравствуйте, я ваша ведьма! Трилогия
Здравствуйте, я ваша ведьма!
Фантастика:
юмористическая фантастика
рейтинг книги
Мое ускорение
5. Девяностые
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Прорвемся, опера! Книга 2
2. Опер
Фантастика:
попаданцы
альтернативная история
рейтинг книги
Невеста напрокат
Любовные романы:
любовно-фантастические романы
рейтинг книги
Если твой босс... монстр!
Любовные романы:
любовно-фантастические романы
рейтинг книги
Приватная жизнь профессора механики
Проза:
современная проза
рейтинг книги
