多线程之Phaser

来源:互联网 发布:手机c语言编程软件6.0 编辑:程序博客网 时间:2024/06/03 18:56

简介

Phaser由java7中推出,是java7中新增的一个使用同步工具,在功能上面它与CyclicBarrier、CountDownLatch有些重叠,但是它提供了更加灵活、强大的用法。

CyclicBarrier,允许一组线程互相等待,直到到达某个公共屏障点。它提供的await()可以实现让所有参与者在临界点到来之前一直处于等待状态。

CountDownLatch,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。它提供了await()、countDown()两个方法来进行操作。

在Phaser中,它把多个线程协作执行的任务划分为多个阶段,编程时需要明确各个阶段的任务,每个阶段都可以有任意个参与者,线程都可以随时注册并参与到某个阶段。


Phaser代替CountDownLatch

package com.example.demo.three.untils.phaser;import java.util.concurrent.Phaser;import java.util.concurrent.TimeUnit;/** * @Author: CYM * @Description: * @Data: 2017/10/14 21:01 */public class PhaserTest1 {    public static void main(String[] args) {        final Phaser phaser = new Phaser(6);        for (int i = 1; i <= 5; i++) {            new Task(phaser).start();        }        phaser.arriveAndAwaitAdvance();        System.out.println("===========");    }    static class Task extends Thread {        private final Phaser phaser;        Task(Phaser phaser) {            this.phaser = phaser;        }        @Override        public void run() {            System.out.println("working: +" + Thread.currentThread().getName()+"--");            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }            phaser.arriveAndAwaitAdvance();        }    }}

Phaser代替CyclicBarrier

package com.example.demo.three.untils.phaser;import java.util.concurrent.Phaser;import java.util.concurrent.TimeUnit;/** * @Author: CYM * @Description: * @Data: 2017/10/14 21:01 */public class PhaserTest2 {    /**     * 所有线程执行完A,再执行B,所有线程执行完B后,再执行C.........     * 类似 : CyclicBarrier     * @param args     */    public static void main(String[] args) {        final Phaser phaser = new Phaser(3);        for (int i = 1; i <= 3; i++) {            new Task(phaser).start();        }    }    static class Task extends Thread {        private final Phaser phaser;        Task(Phaser phaser) {            this.phaser = phaser;        }        @Override        public void run() {            try {                System.out.println( Thread.currentThread().getName()+"-----A-----start");                TimeUnit.SECONDS.sleep(2);                System.out.println( Thread.currentThread().getName()+"-----A-----end");                phaser.arriveAndAwaitAdvance();                System.out.println( Thread.currentThread().getName()+"-----B-----start");                TimeUnit.SECONDS.sleep(2);                System.out.println( Thread.currentThread().getName()+"-----B-----end");                phaser.arriveAndAwaitAdvance();                System.out.println( Thread.currentThread().getName()+"-----C-----start");                TimeUnit.SECONDS.sleep(2);                System.out.println( Thread.currentThread().getName()+"-----C-----end");                phaser.arriveAndAwaitAdvance();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

Phaser一些方法

package com.example.demo.three.untils.phaser;import java.util.concurrent.Phaser;import java.util.concurrent.TimeUnit;/** * @Author: CYM * @Description: * @Data: 2017/10/14 21:01 */public class Test {    /**     * @param args     */    public static void main(String[] args) throws InterruptedException {        final Phaser phaser = new Phaser(1);        //getPhase()获取到达第几个屏障 Returns the current phase number.        System.out.println("getPhase: " + phaser.getPhase()); //0        phaser.arriveAndAwaitAdvance();        System.out.println("getPhase: " + phaser.getPhase()); //1        phaser.arriveAndAwaitAdvance();        System.out.println("getPhase: " + phaser.getPhase()); //2        /**-------------------------------------------------------------------------------------------------*/        //getRegisteredParties获取注册partis的数量   Returns the number of parties registered at this phaser        System.out.println("getRegisteredParties: " + phaser.getRegisteredParties());//1        //register()动态添加一个partis        phaser.register();        System.out.println("getRegisteredParties: " + phaser.getRegisteredParties());//2        //bulkRegister()批量增加partis        phaser.bulkRegister(2);        System.out.println("getRegisteredParties: " + phaser.getRegisteredParties());//4        /**-------------------------------------------------------------------------------------------------*/        final Phaser phaser3 = new Phaser(4);        phaser3.arriveAndDeregister();//parties减少一个        System.out.println("getRegisteredParties1: " + phaser3.getRegisteredParties());//3        /**-------------------------------------------------------------------------------------------------*/        final Phaser phaser2 = new Phaser(5);        for (int i = 1; i <= 3; i++) {            new Task(phaser2).start();        }        TimeUnit.SECONDS.sleep(2);        //getArrivedParties()已被使用partis        //getUnarrivedParties()未被使用partis        System.out.println("getArrivedParties:" + phaser2.getArrivedParties());  //3        System.out.println("getUnarrivedParties:" + phaser2.getUnarrivedParties());//2    }    static class Task extends Thread {        private final Phaser phaser;        Task(Phaser phaser) {            this.phaser = phaser;        }        @Override        public void run() {            phaser.arriveAndAwaitAdvance();        }    }}

onAdvance(int phase, int registeredParties)

package com.example.demo.three.untils.phaser;import java.util.concurrent.Phaser;import java.util.concurrent.TimeUnit;/** * @Author: CYM * @Description: * @Data: 2017/10/14 21:01 */public class Test2 {    /**     * @param args     */    public static void main(String[] args) throws InterruptedException {        final Phaser phaser4 = new Phaser(3){            /**             * @param phase  到达第几个屏障             * @param registeredParties  注册Parties数量             * @return  true 第一次phaser.arriveAndAwaitAdvance()后,调用此方法,之后Phaser呈无效/销毁状态             *          false 多次调用phaser.arriveAndAwaitAdvance(),Phaser继续工作             */            @Override            protected boolean onAdvance(int phase, int registeredParties) {                System.err.println("进入onAdvance:" + phase+registeredParties);                return true;            }        };        for (int i = 1; i <= 3; i++) {            new Task(phaser4).start();        }    }    static class Task extends Thread {        private final Phaser phaser;        Task(Phaser phaser) {            this.phaser = phaser;        }        @Override        public void run() {            try {                System.out.println(Thread.currentThread().getName()+"---1---");                TimeUnit.SECONDS.sleep(2);                phaser.arriveAndAwaitAdvance();                TimeUnit.SECONDS.sleep(2);                System.out.println(Thread.currentThread().getName()+"===2===");                System.out.println("是否销毁:" + phaser.isTerminated());                if (Thread.currentThread().getName().equals("Thread-0")){                    TimeUnit.SECONDS.sleep(10);                }                phaser.arriveAndAwaitAdvance();                TimeUnit.SECONDS.sleep(1);                System.out.println("*********");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

arrive()

跟arriveAndAwaitAdvance()相比,不用等待。

public static void main(String[] args) throws InterruptedException {        final Phaser phaser = new Phaser(2);        new Thread(phaser::arrive).start(); //Arrives at this phaser,without waiting for others to arrive.        System.out.println("*********");        new Thread(phaser::arriveAndAwaitAdvance).start();        System.out.println("*********");    }

awaitAdvance(phase)

如果当前传入参数phase和getPhase()方法返回的值一样。则在屏障处等待,直到两者值不一样。不可被打中断。并不参与parties计数。

public class Test4 {    /**     * @param args     */    public static void main(String[] args) throws InterruptedException {        final Phaser phaser = new Phaser(4);        for (int i = 0; i <= 3; i++) {            new Task(phaser).start();        }        final int phase = phaser.getPhase();        /**awaitAdvance(phase):如果当前传入参数phase和getPhase()方法         * 返回的值一样。则在屏障处等待,直到两者值不一样。不可被打中断         *         * 分析:传入参数phase=0,phaser.awaitAdvance(0)会一直等待,当第一次所有线程         * 执行到phaser.arriveAndAwaitAdvance(),这时phaser.getPhase()为1,phaser.awaitAdvance(0)         * 放行。         *         * 输出结果: *****1****1                     *****1****1                     *****1****1                     *****1****1                     *********0                     *****2****2                     *****2****2                     *****2****2                     *****2****2         */        phaser.awaitAdvance(phase);        System.out.println("*********" + phase);        /**----------------------------------------*/        /**         * awaitAdvance(int phase) 并不参与parties计数         *         * 结果:从输出结果可以看到:phaser1.getArrivedParties()为0         */        final Phaser phaser1 = new Phaser(4);        new Thread(()->phaser1.awaitAdvance(0)).start();        TimeUnit.SECONDS.sleep(20);        System.err.println(phaser1.getArrivedParties());    }    static class Task extends Thread {        private final Phaser phaser;        Task(Phaser phaser) {            this.phaser = phaser;        }        @Override        public void run() {            try {                TimeUnit.SECONDS.sleep(1);                phaser.arriveAndAwaitAdvance();                System.out.println("*****1****"+phaser.getPhase());                TimeUnit.SECONDS.sleep(1);                phaser.arriveAndAwaitAdvance();                System.out.println("*****2****"+phaser.getPhase());            } catch (Exception e) {                e.printStackTrace();            }        }    }}

awaitAdvanceInterruptibly(int phase)可被中断.
awaitAdvanceInterruptibly(int phase,long timeout, TimeUnit unit) 最多等待指定时间,可中断.


forceTermination()

 public static void main(String[] args) throws InterruptedException {        final Phaser phaser = new Phaser(3);        new Thread(phaser::arriveAndAwaitAdvance).start();        TimeUnit.SECONDS.sleep(3);        System.out.println(phaser.isTerminated());        phaser.forceTermination();        System.out.println(phaser.isTerminated());    }
原创粉丝点击