Защелки необходимы тогда, когда необходимо ускорить выполнение последовательных независимых задач за счет их распараллеливания. Раз уж я остановился на строительных примерах, то ситуацией их жизни может служить приготовление бетона.
В моем случае бетон состоит из 4 составляющих: песок, цемент, щебень и вода. Допустим, что все материалы для приготовления бетона находятся на разном расстоянии от емкости, где его приготавливают.
При последовательном выполнении данных операций нам небходима сумма времени на выполнение каждой операции. Если у нас в распоряжении есть 4 работника, то время наполнения емкости, готовой к замесу, становится равно времени выполнения максимальной операции.
Дополнительным условием для начала замеса является полное заполнение емкости.
Рассмотрим на примере кода.
1. Главный класс, где создаются работники и защелка на 4 события. Этот класс ожидает завершения работы всех работников (latch.await())
2. Класс для генерации случайного времени задержки (время условно определяет удаленность материала от емкости)
3.Класс работника, который выполняет задачу и извещает о выполнении
Результат выполнения программы
По результатам работы видно, что общее время выполнения программы 960 мс, а при последовательном выполнении мы б получили время, равное сумме: 720 + 887 + 927 + 959 = 3493 мс.
В данном примере использована библиотека guava для подсчета времени выполнения метода.
Примером для параллельного выполнения из мира Java может служить получение данных о клиенте. На входе в программу мы имеем некий userId клиента и из разных источников запрашиваем данные. Например, по http-запросу №1 мы получаем фамилию и имя клиента, запросом в базу данных год рождения и запросом №2 получаем список банковских счетов.
В моем случае бетон состоит из 4 составляющих: песок, цемент, щебень и вода. Допустим, что все материалы для приготовления бетона находятся на разном расстоянии от емкости, где его приготавливают.
При последовательном выполнении данных операций нам небходима сумма времени на выполнение каждой операции. Если у нас в распоряжении есть 4 работника, то время наполнения емкости, готовой к замесу, становится равно времени выполнения максимальной операции.
Дополнительным условием для начала замеса является полное заполнение емкости.
Рассмотрим на примере кода.
1. Главный класс, где создаются работники и защелка на 4 события. Этот класс ожидает завершения работы всех работников (latch.await())
import com.google.common.base.Stopwatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) throws InterruptedException { Stopwatch sw = new Stopwatch(); sw.start(); CountDownLatch latch = new CountDownLatch(4); new Worker(latch,"Sand").start(); new Worker(latch,"Cement").start(); new Worker(latch,"Water").start(); new Worker(latch,"Breakstone").start(); System.out.println("Waiting for all workers"); latch.await(); System.out.println("All workers finished. Now we can shake."); sw.stop(); System.out.println("Program time: " + sw.elapsed(TimeUnit.MILLISECONDS) + " ms"); } }
2. Класс для генерации случайного времени задержки (время условно определяет удаленность материала от емкости)
public class RandomGenerator { public static long getRandom(long min, long max) { return min + (long)(Math.random() * (max - min + 1)); } }
3.Класс работника, который выполняет задачу и извещает о выполнении
import com.google.common.base.Stopwatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class Worker extends Thread { private CountDownLatch _cdl; private String _name; public Worker (CountDownLatch cdl, String name) { _cdl = cdl; _name = name; } @Override public void run() { Stopwatch sw = new Stopwatch(); sw.start(); System.out.println(_name + " working..."); try { Thread.sleep(RandomGenerator.getRandom(500, 1000)); } catch (InterruptedException e) { e.printStackTrace(System.err); } _cdl.countDown(); sw.stop(); System.out.println(_name + " time: " + sw.elapsed(TimeUnit.MILLISECONDS) + " ms"); } }
Результат выполнения программы
Sand working... Breakstone working... Waiting for all workers Water working... Cement working... Water time: 720 ms Sand time: 887 ms Cement time: 927 ms Breakstone time: 959 ms All workers finished. Now we can shake. Program time: 960 ms
По результатам работы видно, что общее время выполнения программы 960 мс, а при последовательном выполнении мы б получили время, равное сумме: 720 + 887 + 927 + 959 = 3493 мс.
В данном примере использована библиотека guava для подсчета времени выполнения метода.
Примером для параллельного выполнения из мира Java может служить получение данных о клиенте. На входе в программу мы имеем некий userId клиента и из разных источников запрашиваем данные. Например, по http-запросу №1 мы получаем фамилию и имя клиента, запросом в базу данных год рождения и запросом №2 получаем список банковских счетов.