Skip to content

Instantly share code, notes, and snippets.

@sunwu51
Last active March 20, 2023 13:38
Show Gist options
  • Save sunwu51/0cc15f42c6923a1498d869a85b6d905b to your computer and use it in GitHub Desktop.
Save sunwu51/0cc15f42c6923a1498d869a85b6d905b to your computer and use it in GitHub Desktop.
phaser题目

题目

有4线程,分阶段执行任务,第0阶段,需4个都执行完才能开始下一阶段。第1阶段,需3个都执行完才能开始下一阶段。第2阶段,需2个都执行完才算最终完成。

public class Main{
    public static void main(String[] args) {
        test();
    }
    static void test(){
        Phaser phaser = new Phaser(4);
        for(int i=0;i<4;i++){
            new Thread(()->{
                sleep(3);
                exec(0);
                arrive(phaser, 0);
                phaser.awaitAdvance(0);

                sleep(30);
                exec(1);
                arrive(phaser, 1);
                phaser.awaitAdvance(1);// 注释: 如果当前phase不等于1,则这句就不会阻塞,视频里讲过

                sleep(3);
                exec(2);
                arrive(phaser, 2);
                phaser.awaitAdvance(2);
            }).start();
        }
        phaser.awaitAdvance(0);
        System.out.println("阶段0完成");
        phaser.arriveAndDeregister();  // 注释:arriveAndDeregister的作用是总数-1(未完成数-1 )
        phaser.awaitAdvance(1);
        System.out.println("阶段1完成");
        phaser.arriveAndDeregister();
        phaser.awaitAdvance(2);
        System.out.println("阶段2完成即完成");
    }

    static synchronized void arrive(Phaser phaser, int phase){
        if(phaser.getPhase() == phase){
            phaser.arrive();
        }
    }
    static void sleep(int i){
        try {
            Thread.sleep(new Double(Math.random()*1000*i).longValue());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static void exec(int x){
        System.out.println(Thread.currentThread().getName()+"执行任务"+x);
    }
}
@donnieYeh
Copy link

从b站过来的,实际上在主线程里多调一次arrive还是有问题的,在a线程释放屏障准备进入下一阶段的过程中,b线程调用arrive,就会有冲突。把睡眠时间去掉,循环test ()100次就可以复现该问题,目前我也没想到什么好方法呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment