基于CAS的一些锁(4)- Phaser

phase 是阶段的意思。Phaser是按照不同阶段执行线程的,就像是结合了CountDownLatch和CyclicBarrier,它本身维护着一个叫 phase 的成员变量代表当前执行的阶段。

如果程序中遇到分好几个阶段执行,并且有的阶段需要多个线程共同参与的情况下可能会用到Phase。

示例:

这里模拟了一个结婚的场景

自定义一个MarriagePhaser 继承 Phaser 重写Phaser的onAdvance方法定义了4个阶段(进入下一个阶段时该方法被自动调用)。
阶段必须从0开始。onAdvice的两个参数 phase是第几个阶段,registeredParties是目前有几个已注册线程参加。
最后返回值为false表示流程未结束,继续执行下一阶段,返回true表示流程结束。

Persion的run方法中有四种行为对应四个阶段

public class T04_Phaser {

    static Random r = new Random();
    static MarriagePhaser phaser = new MarriagePhaser();

    static class MarriagePhaser extends Phaser {
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            // 定义4个阶段,一个阶段结束时该方法被自动调用
            switch (phase) {
                case 0:
                    System.out.println("所有人到齐!" + registeredParties + "\n");
                    return false; // 流程未结束,继续
                case 1:
                    System.out.println("所有人都吃完饭了!" + registeredParties + "\n");
                    return false; // 流程未结束,继续
                case 2:
                    System.out.println("客人都离开了!" + registeredParties + "\n");
                    return false; // 流程未结束,继续
                case 3:
                    System.out.println("婚礼结束!" + registeredParties + "\n");
                    return true; // 流程结束
                default:
                    return true;

            }
        }
    }
    // 定义Persion类,实现Runnable ,重写run方法参加婚礼
    static class Persion implements Runnable {

        String name;

        public Persion(String name){
            this.name = name;
        }

        // 提取sleep方法
        public void secondsSleep(int seconds) {
            try {
                TimeUnit.SECONDS.sleep(seconds);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 阶段 1 行为
        public void arrive() {
            secondsSleep(2);
            System.out.println(name + "到达现场!");
            phaser.arriveAndAwaitAdvance(); // 阶段结束放行
        }

        // 阶段 2 行为
        public void eat() {
            secondsSleep(2);
            System.out.println(name + "吃完饭!");
            phaser.arriveAndAwaitAdvance(); // 阶段结束放行
        }

        // 阶段 3 行为
        public void leave() {
            if ("新郎".equals(name) || "新娘".equals(name)) {
                secondsSleep(2);
                System.out.println(name + "留下!");
                phaser.arriveAndAwaitAdvance(); // 阶段结束放行
            } else {
                System.out.println(name + "离开!");
                /*
                 * 客人离开后从phaser中注销,不再受阶段控制
                 *
                 * 注意:这时客人的线程并没有结束,只是不再受phaser影响可自由往下执行
                 *
                 * 注销后可减少下一阶段中需要提前加入的线程,提高效率
                 */
                phaser.arriveAndDeregister(); // 从phaser中注销
            }

        }

        // 阶段 4 行为 
        public void hug() {
            if ("新郎".equals(name) || "新娘".equals(name)) {
                secondsSleep(2);
                System.out.println(name + "拥抱!");
                phaser.arriveAndAwaitAdvance();
            }
        }

        @Override
        public void run() {
            arrive();
            eat();
            leave();
            hug();
        }
    }

    public static void main(String[] args) {
        // 注册7个线程
        phaser.bulkRegister(7);

        for (int i = 0; i < 5; i++) {
            new Thread(new Persion("客人" + i)).start();
        }
        new Thread(new Persion("新郎")).start();
        new Thread(new Persion("新娘")).start();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值