zoukankan      html  css  js  c++  java
  • java多线程之Phaser

    简介:

    java多线程技术提供了Phaser工具类,Phaser表示“阶段器”,用来解决控制多个线程分阶段共同完成任务的情景问题。其作用相比CountDownLatch和CyclicBarrier更加灵活。

    Phaser是按照不同的阶段对线程进行执行,就是它本身是维护者一个阶段这样的成员变量,当前我是执行到哪个阶段,是第0个,还是第1个阶段,每个阶段不同的时候这个线程都可以往前走,有的线程走到某个阶段停了,有的线程一直会走到结束。你的程序中如果说用到好几个阶段执行,而且有的阶段必须得几个线程共同参与的一种情况下就会使用到Phaser。

    下面来看一个小例子。模拟了一个结婚的场景,结婚是好多人都要参加的,因此,我们写了一个类Person是一个runnable可以new出来的,扔给Thread去执行,模拟我们每个人要做的事情。有这么几个方法 arrive() ,eat(). leave(), hug() 。作为一个婚礼来讲,它会分成几个阶段,第一阶段大家都到齐,第二阶段开始吃饭,第三个阶段大家离开,最后新郎新娘进入洞房。

    package com.msb.demo;
    
    import java.util.Random;
    import java.util.concurrent.Phaser;
    import java.util.concurrent.TimeUnit;
    
    public class Phaser_Demo {
    
        static Random r = new Random();
    
        static MarriagePhaser phaser = new MarriagePhaser();
    
        static void milliSleep(int milli){
            try {
                TimeUnit.MICROSECONDS.sleep(milli);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    
        public static void main(String[] args) {
            phaser.bulkRegister(7);
    
            for (int i = 0; i < 5; i++) {
                new Thread(new Person("p" + i)).start();
            }
    
            new Thread(new Person("新郎")).start();
            new Thread(new Person("新娘")).start();
    
    
        }
    
        static class MarriagePhaser extends Phaser{
    
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
    
                switch (phase){
                    case 0 :
                        System.out.println("所有人都到齐了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 1:
                        System.out.println("所有人都吃完了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 2:
                        System.out.println("所有人都离开了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 3:
                        System.out.println("婚礼结束!新郎新娘抱抱!" + registeredParties);
                        System.out.println();
                        return true;
                    default:
                        return true;
                }
            }
        }
    
        static class Person implements Runnable{
    
            String name;
    
            public Person(String name) {
                this.name = name;
            }
    
            public void arrive(){
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 到达现场!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
    
            public void eat(){
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 吃完!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
    
            public void leave(){
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 离开!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
    
            public void hug(){
                if(name.equals("新郎") || name.equals("新娘")){
                    milliSleep(r.nextInt(1000));
                    System.out.printf("%s 洞房!
    ", name);
                    phaser.arriveAndAwaitAdvance();
                }else {
                    phaser.arriveAndDeregister();
                }
            }
    
    
            @Override
            public void run() {
                arrive();
                eat();
                leave();
                hug();
            }
        }
    }
    

      

    看下主程序,一个有5个嘉宾来参加婚礼,加上新郎,新娘一共七个人。线程start 会调用people的run方法,依次执行 arrive, eat, leave, hug 方法。那好,我们在每个阶段是不是都应该控制好人数,第一个阶段人都到齐了,婚礼才能开始。第二阶段所有人吃饭,第三阶段所有人离开,但是到了第四阶段并不是所有人进入洞房。所以,要把婚礼分成几个阶段,而且每个阶段必须等相应的人干完自己的事情,才能进入下一阶段。

    看下程序的输出:

    p0 到达现场!
    p2 到达现场!
    p1 到达现场!
    p4 到达现场!
    p3 到达现场!
    新郎 到达现场!
    新娘 到达现场!
    所有人都到齐了!7

    新娘 吃完!
    p0 吃完!
    p2 吃完!
    p3 吃完!
    新郎 吃完!
    p1 吃完!
    p4 吃完!
    所有人都吃完了!7

    p3 离开!
    新娘 离开!
    p4 离开!
    p0 离开!
    新郎 离开!
    p2 离开!
    p1 离开!
    所有人都离开了!7

    新娘 洞房!
    新郎 洞房!
    婚礼结束!新郎新娘抱抱!2


    Process finished with exit code 0

    程序定义了一个 marriagePhaser 继承了phaser,并重写了onAdvance方法,所有的程序第一次调用arriveAndAwaitAdvance这个方法,phaser的onAdvance方法会自动调用,phase参数代表第几阶段,初始为0; registeredParties 代表这个阶段有几个线程参加。返回false进入下一阶段,返回true,所有线程结束,phaser整个栅栏组结束。 phaser.arriveAndDeregister() 取消参与后面的阶段, phaser.register 往上增加,不仅可以控制栅栏上的个数还可以控制栅栏上的等待数量。

  • 相关阅读:
    IOS Block-Block块的使用与理解
    IOS 多线程03-GCD
    IOS 多线程01-线程基础知识
    JavaScript高级-定义函数(类)方法
    互联网技术笔试总通不过?leetcode刷对了么
    Redis 内存满了怎么办? Redis的内存淘汰策略
    SpringBoot项目优化和Jvm调优
    中台的末路
    Java 应用中的日志
    Spring Boot 支持https
  • 原文地址:https://www.cnblogs.com/xues/p/14254736.html
Copyright © 2011-2022 走看看