写在前面
今天我们来学习多线程中另一个工具,Phaser,一个比CyclicBarrier更灵活的工具,同CyclicBarrier一样,也是要保证所有线程同时到达某个点时才能继续执行。
下面就一起来看一下Phaser到底有哪些过人之处吧。
学习多线程之Phaser使用
Phaser虽然和CyclicBarrier工具都提供了差不多的功能,但是Phaser显然更加灵活,此工具更注重其的可重复使用的特征。
并且在这个特征上可以支持多个线程多次进行并发操作,提供了周期停顿的方法,可以中间停顿等待所有线程,并且这个周期可以是多个。
还是要从它的代码示例中才能更清楚的看出来,代码相对就比较复杂了,来一步步的看吧。
首先,来定义一下周期操作,这个过程需要继承Phaser类,如下代码:
public class TestPhaser extends Phaser { public boolean cycle(int cycleNum){ boolean flag = false; if(cycleNum == 1){ System.out.println("第一站"+getRegisteredParties()); }else if(cycleNum == 2){ System.out.println("第二站"+getRegisteredParties()); }else if(cycleNum == 3){ System.out.println("最后一站"); flag = true; } return flag; } }
通过这个周期,我们在定义一个方法来调用执行他。
public static void main(String[] args) { TestPhaser testPhaser = new TestPhaser(); Thread thread0 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { testPhaser.register(); System.out.println("thread0第一站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread0第二站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread0最后一站"); testPhaser.arriveAndAwaitAdvance(); } }); Thread thread1 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { testPhaser.register(); System.out.println("thread1第一站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread1第二站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread1最后一站"); testPhaser.arriveAndAwaitAdvance(); } }); Thread thread2 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { testPhaser.register(); System.out.println("thread2第一站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread2第二站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread2最后一站"); testPhaser.arriveAndAwaitAdvance(); } }); Thread thread3 = new Thread(new Runnable() { @SneakyThrows @Override public void run() { testPhaser.register(); System.out.println("thread3第一站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread3第二站"); testPhaser.arriveAndAwaitAdvance(); System.out.println("thread3最后一站"); testPhaser.arriveAndAwaitAdvance(); } }); thread0.start(); thread1.start(); thread2.start(); thread3.start(); }
通过这个代码,我们可以得到如下的效果:
thread1第一站
thread3第一站
thread0第一站
thread2第一站
thread2第二站
thread1第二站
thread3第二站
thread0第二站
thread0最后一站
thread1最后一站
thread2最后一站
thread3最后一站
这个结果,是我们想要得到的效果,这几个线程,先执行了第一站,接着第二站,依次执行后得到了这个结果。
大家也可以自行去尝试一番。