Разница между Phaser и CyclicBarrier
Я наткнулся на сомнение относительно различий между утилитами CyclicBarrier и Phaser в параллельном пакете Java.
Я понимаю, что CyclicBarrier позволяет группе потоков ждать, пока все потоки не достигнут определенной точки. Phaser также делает то же самое, но поддерживает несколько фаз. Я также понимаю, что CyclicBarrier можно использовать повторно. Я думаю, что это средство повторного использования делает его функцию такой же, как Phaser.
Рассмотрим следующие программы:
Фазер тестирования:
import java.util.concurrent.Phaser;
public class PhaserTest {
public static void main(String[] args) {
Phaser p = new Phaser(3);
Thread t1 = new Thread(() -> process(p), "T1");
Thread t2 = new Thread(() -> process(p), "T2");
Thread t3 = new Thread(() -> process(p), "T3");
t1.start();
t2.start();
t3.start();
}
private static void process(Phaser p) {
try {
System.out.println("Started Phase 1: "+Thread.currentThread().getName());
p.arriveAndAwaitAdvance();
System.out.println("Finished Phase 1: "+Thread.currentThread().getName());
System.out.println("Started Phase 2: "+Thread.currentThread().getName());
p.arriveAndAwaitAdvance();
System.out.println("Finished Phase 2: "+Thread.currentThread().getName());
} catch(Exception e) {}
}
}
Выход:
Started Phase 1: T1
Started Phase 1: T2
Started Phase 1: T3
Finished Phase 1: T3
Started Phase 2: T3
Finished Phase 1: T1
Finished Phase 1: T2
Started Phase 2: T2
Started Phase 2: T1
Finished Phase 2: T2
Finished Phase 2: T3
Finished Phase 2: T1
Тестирование CyclicBarrier:
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cb = new CyclicBarrier(3);
Thread t1 = new Thread(() -> process(cb), "T1");
Thread t2 = new Thread(() -> process(cb), "T2");
Thread t3 = new Thread(() -> process(cb), "T3");
t1.start();
t2.start();
t3.start();
}
private static void process(CyclicBarrier cb) {
try {
System.out.println("Started Phase 1: "+Thread.currentThread().getName());
cb.await();
System.out.println("Finished Phase 1: "+Thread.currentThread().getName());
System.out.println("Started Phase 2: "+Thread.currentThread().getName());
cb.await();
System.out.println("Finished Phase 2: "+Thread.currentThread().getName());
} catch(Exception e) {}
}
}
Выход:
Started Phase 1: T1
Started Phase 1: T2
Started Phase 1: T3
Finished Phase 1: T3
Started Phase 2: T3
Finished Phase 1: T1
Started Phase 2: T1
Finished Phase 1: T2
Started Phase 2: T2
Finished Phase 2: T2
Finished Phase 2: T3
Finished Phase 2: T1
В PhaserTest и CyclicBarrierTest следующая фаза не начинается, пока все стороны не прибудут / не завершат предыдущую фазу.
Итак, в чем выгода наличия Phaser?
1 ответ
Фазер происходит от JSR-166
При сравнении фазеров с существующими функциями Java поясняется, что поддерживается функциональность, аналогичная классу CyclicBarrier (введена в Java 5), но по своей природе фазеры более гибкие:
Класс [java.util.concurrent] CyclicBarrier поддерживает периодическую барьерную синхронизацию среди набора потоков. В отличие от Phasers, CyclicBarriers не поддерживают динамическое добавление или удаление потоков; они также не поддерживают одностороннюю синхронизацию или работу в двухфазном режиме. Одним из основных мотивов для изучения дополнительных реализаций барьера было не только повышение гибкости, но и повышение производительности и масштабируемости концепции синхронизации барьеров:
Результаты производительности, полученные от переносимой реализации фазеров на трех различных платформах SMP, демонстрируют, что они могут обеспечить превосходную производительность для существующих реализаций барьера, в дополнение к преимуществам производительности, которые вытекают из их универсальности и безопасности.
полное объяснение здесь: https://www.infoq.com/news/2008/07/phasers
Также другая сравнительная статья, определяющая Phaser
как CyclicBarier+CountdownLatch
: http://flex4java.blogspot.com/2015/03/why-and-how-to-use-phaser-in-java.html