JAVA并发同步包之Phaser

   Java并发包中的Phaser功能强大,灵活的同时,也很复杂,不容易理解,Phaser类似于CyclicBarrier和CountDownLatch。相比于CyclicBarrier, Phaser主要有以下特征

  • Phaser不但可以像CyclicBarrier一样,可重复使用,而且能动态变更参与方数量数量,在 CyclicBarrier 中,在创建时,参与方数量是固定的。但是,在Phaser中,可以通过调用register()添加参与方,arriveAndDeregister()方法删除参与方。
  • 一个Phaser有一个相关的phrase号,从0开始。当所有注册方都到达一个Phaser时,Phaser进入下一个phrase,phrase号递增1。phrase号的最大值为Integer.MAX_VALUE(private static final int  MAX_PHASE= Integer.MAX_VALUE;)。最大值后,相位号以零为起点重新开始。类似赛中的回合制。
  • Phaser有一个终止状态。在终止状态下,所有在Phaser上调用的同步方法都会立即返回,而不需要等待预处理
  • Phaser类的onAdvance()方法中写代码来指定一个phaser动作让所有注册方到达 phaser 时执行 phaser 动作。可以在个方法里面返回true,让Phaser不再执行。

用途:主要用于将一些并发任务分成若干个步骤

  例如一个表的数据存储在三个库中,统计一个字段的数据,可以写三个三个线程从三个库中读,在主线程中phaser.arriveAndAwaitAdvance()方法,等待三个线程执行完后,进行统计。

实例

 我们用Phaser模拟一个跑步比赛,选手人数不定,比赛不分轮次,每一轮淘汰跑步时间超过一定时间的选手,直到最后一个胜出为止。

Runner类继承Thread类,代表每一个参赛者,,随机生成一个1到5的整数,,用Thread.sleep()模拟参赛者跑步时长,每一轮都要等所有参赛者都到达后开始,当所有如果用时大于5秒,则淘汰。具体代码:

import java.util.Random;
import java.util.concurrent.Phaser;

public class Runner extends Thread {
    private final String name;
    private final Phaser phaser;
    private static Random rand = new Random();

    public Runner(String name, Phaser phaser) {
        this.name = name;
        this.phaser = phaser;
    }

    @Override
    public void run() {
        while (!phaser.isTerminated()) {
            try {
                phaser.arriveAndAwaitAdvance();
                if(phaser.getArrivedParties() == 1) {
                    System.out.println(String.format("%s win", name));
                    phaser.arriveAndDeregister();
                    return;
                }
                int sleepTime = rand.nextInt(5) + 1;
                Thread.sleep(sleepTime * 1000);
                System.out.println(String.format("%s run Time:%d", name, sleepTime));
                if (sleepTime >= 5) {
                    phaser.arriveAndDeregister();
                    System.out.println(String.format("%s run Time:%d  out", name, sleepTime));
                    return;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

RunnerTest类里实现了Phaser类,重载了onAdvance()方法。

import java.util.concurrent.Phaser;

public class RunnerTest {
    public static void main(String[] args) {
        final Integer PERSON_COUNT = 3;
        Phaser phaser = new Phaser() {
            @Override
            protected boolean onAdvance(int phase, int parties) {
                System.out.println(String.format("%d arrive phase :%d", parties, phase));
                if (parties == 1) {
                    return true;
                }
                System.out.println("------------------");
                return false;
            }
        };
        phaser.bulkRegister(PERSON_COUNT);
        for (int i = 0; i < PERSON_COUNT; i++) {
            Runner person = new Runner("Runner" + i, phaser);
            person.start();
        }

    }
}

运行结果:

3 arrive phase :0
------------------
Runner1 run Time:1
Runner2 run Time:4
Runner0 run Time:5
2 arrive phase :1
------------------
Runner0 run Time:5  out
Runner1 run Time:4
Runner2 run Time:5
1 arrive phase :2
Runner2 run Time:5  out
Runner1 win

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值