Java并发基础(五)-CountDownLatch、CyclocBarrier、Phaser的使用

来源:互联网 发布:推广数据留言 编辑:程序博客网 时间:2024/05/18 00:13

1. CountDownLatch

一个同步工具,允许一个或多个线程去等待其他线程中执行的一系列操作完成。

什么意思呢?就是说,允许这个线程阻塞,直到,其他线程的所有操作都完成之后,在继续执行。举个例子。

    public static void main(String[] args) throws InterruptedException {        final CountDownLatch downLatch = new CountDownLatch(5);        new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 5; i++) {                    System.err.println(i);                    try {                        Thread.sleep(1000);                        downLatch.countDown();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();        downLatch.await();        System.err.println("结束了");    }

上面的例子 等五个线程都执行完毕之后,主线程才会继续执行。

用法如下:

  • CountDownLatch(5) 后面的数字代表等待几个线程完成
  • 每当一个线程完成的时候,downLatch.countDown(),来使计数-1
  • downLatch.await() ,直到计数为0的时候,才会执行他下面的逻辑。

2. CyclocBarrier

也是一个同步工具,允许一系列线程等待其中每一个都到达一个公共的障碍点,然后在继续执行。并且,等待的线程都释放之后,可以重用

作为山沟沟里的娃,受够了坐车等人的折磨。举个例子。

    public static void main(String[] args){        final CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {            @Override            public void run() {                System.err.println("到齐了。可以开车了");            }        });        for (int i = 0; i < 5; i++) {            final int finalI = i;            new Thread(new Runnable() {                @Override                public void run() {                    System.err.println("买票了"+ finalI);                    try {                        cyclicBarrier.await();                        System.err.println("起飞了"+ finalI);                    } catch (InterruptedException e) {                        e.printStackTrace();                    } catch (BrokenBarrierException e) {                        e.printStackTrace();                    }                }            }).start();        }    }

输出结果:
这里写图片描述

用法:

  • CyclicBarrier(int parties, Runnable barrierAction) 构造函数中,参数一个是调用await的线程数,一个是到达障碍点之后的处理。
  • cyclicBarrier.await() 表示我要等其他也到达,才要继续执行

3. Phaser

一个可重用的同步工具,可以实现提CyclicBarrier和CountDownLatch的功能,但是还有其他高级的功能。

3.1 实现CountDownLatch的功能

  • CountDownLatch#countDown 由Phaser#arrive 代替
  • CountDownLatch#await 由Phaser#awaitAdvance 代替

举个例子:

        final Phaser phaser = new Phaser(5);        for (int i = 0; i < 5; i++) {            final int finalI = i;            new Thread(new Runnable() {                @Override                public void run() {                    System.err.println(finalI);                    phaser.arrive();                }            }).start();        }        phaser.awaitAdvance(phaser.getPhase());        System.err.println("结束了");

3.2 实现CyclocBarrier的功能

虽然说能实现,但是还是比较弱。

  • CyclicBarrier#await 由Phaser#arriveAndAwaitAdvance代替。
        final Phaser phaser = new Phaser(5);        for (int i = 0; i < 5; i++) {            final int finalI = i;            new Thread(new Runnable() {                @Override                public void run() {                    System.err.println("买票了"+ finalI);                    phaser.arriveAndAwaitAdvance();                    System.err.println("起飞了"+ finalI);                }            }).start();        }

3.3 高级功能

  • 支持register和bulkRegister方法来调整任务数,arriveAndDeregister方法支持在任务到达的时候减少任务数
  • arriveAndAwaitAdvance 表示任务到达并且等待其他任务到达
  • 支持终止,如果onAdvance返回true,就会终止,如果注册任务数为0,也会终止。forceTermination方法会强制终止。
  • 从它的构造函数来看,Phaser支持分层,Phaser(Phaser parent, int parties)。可以通过这些来构造出一个层次的Phaser

这些功能就不举例子了。有兴趣的同学可以去看下文档。

参考资料

  • JDK Phaser
  • What’s New on Java 7 Phaser
1 0
原创粉丝点击