Phaser和CyclicBarrier之间的区别

Sha*_*war 7 java java.util.concurrent

我偶然发现了Java并发包中CyclicBarrier和Phaser实用程序之间的区别.

我知道CyclicBarrier允许一组线程等到所有线程到达特定点.Phaser也做同样的事情,但它支持多个阶段.我也明白,CyclicBarrier可以重复使用.我认为这个重用工具使其功能与Phaser相同.

考虑以下程序:

测试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) {}
    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

测试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) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

在PhaserTest和CyclicBarrierTest中,直到所有各方到达/完成前一阶段才开始下一阶段.

那么,拥有Phaser的好处是什么?

小智 5

Phaser 来自JSR-166

将移相器与现有 Java 功能进行比较时,会解释为支持与 CyclicBarrier 类类似的功能(在 Java 5 中引入),但移相器本质上更灵活:

[java.util.concurrent] CyclicBarrier 类支持一组线程之间的周期性屏障同步。然而,与 Phaser 不同的是,CyclicBarriers 不支持动态添加或删除线程;它们也不支持单向同步或分相操作。探索其他屏障实现的主要动机之一不仅是为了提高灵活性,而且是为了提高屏障同步概念的性能和可扩展性:

从移相器在三个不同 SMP 平台上的可移植实现中获得的性能结果表明,除了由于其通用性和安全特性带来的生产力优势之外,它们还可以提供优于现有屏障实现的性能。

完整解释在这里:https : //www.infoq.com/news/2008/07/phasers

还有另一篇比较文章定义PhaserCyclicBarier+CountdownLatchhttp : //flex4java.blogspot.com/2015/03/why-and-how-to-use-phaser-in-java.html