CyclicBarrier в Java

Принцып работы CyclicBarrier такой: потоки зависают друг за другом в месте вызова в них await. Когда зависло необходимое количество потоков, зависнувшие потоки развисают и запускается другой дополнительный отдельный поток в котором можно что-то сделать, например обработать данные, полученные в предыдущих потоках.

В примере ниже мы создаем переменную volatile и потоки добавляют к ней 1, потом в месте await они останавливаются и когда зависнет указанное в CyclicBarrier количество потоков потоки развисают и сразу после этого запускается метод run в классе Run. И в этом методе run класса Run будет использована эта ранее изменяемая зависающими потоками переменная.

Пример программы:

import java.io.*; import java.util.concurrent.CyclicBarrier; class CyclicBarrierExample { //к этой переменной добавляется 1 //в потоках SomeThread static volatile int j; public static void main(String[] args) { //Только когда на await зависнут три потока все //зависнувшие потоки развиснут. //и метод run в классе Run запуститься только //когда все три потока дойдут до await CyclicBarrier cycbar = new CyclicBarrier(6, new Run()); for (int i = 1; i < 7; i++){ SomeThread t = new SomeThread(); t.setName("Thread "+ i); t.cycbar = cycbar; t.start(); } } //здесь в Run выводиться результирующее j static class Run extends Thread { @Override public void run(){ System.out.println(j); } } static class SomeThread extends Thread{ CyclicBarrier cycbar; @Override public void run(){ try{ j++; System.out.println( Thread.currentThread().getName()+" "+j); cycbar.await(); //здесь поток зависает System.out.println( Thread.currentThread().getName() + " is alive again"); } catch(Exception e){} } } }

Вывод:

Как видим шесть потоков остановили свою работу, потом запустился поток Run и вывел 6 и потом потоки продолжили работу.

Корректная остановка потоков с помощью Interrupt

Узнайте, как правильно останавливать потоки в Java с помощью interrupt(). Почему Thread.stop() опасен и как использовать isInterrupted() для безопасного завершения работы потоков.
Time to read: 14

Callable в Java

Callable vs Runnable: как возвращать результат из потока в Java. Примеры использования FutureTask для получения результатов асинхронных операций.
Time to read: 12

ExecutorService: управление пулом потоков

Изучите ExecutorService в Java для эффективного управления пулом потоков. Уменьшайте накладные расходы, переиспользуя потоки в многопоточных приложениях.
Time to read: 15