多线程并发工具类之Phaser

多线程并发工具类之Phaser

书籍

《Java并发编程的艺术》—方腾飞,第8章

场景说明

一批运动员参加一场比赛,比赛分为3个阶段:选手入场-开始比赛-比赛结束。所有的选手完成一个阶段后才能开始下个阶段,否则等待其他选手完成该阶段,比如所有选手入场后才能开始比赛。

实例代码

1、自定义Phaser类

package java7.thread.chapter2.test1;

import java.util.concurrent.Phaser;

public class MyPhaser extends Phaser {
    // 总共3个阶段
    private int allPhase = 2;
	
    @Override
    protected boolean onAdvance(int phase, int registeredParties) {
        // 阶段完成后todo,可用switch-case根据每个阶段做不同的事
        System.out.println("--第" + (phase + 1) + "阶段已完成--");

        // 到达结束阶段,或者没到达结束阶段但是注册线程数为0,返回true
        // Phaser阶段改变时自动执行。返回true结束,false继续执行
        return phase == allPhase || registeredParties == 0;
    }
}

2、任务类

package java7.thread.chapter2.test1;

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

public class Player implements Runnable {

    private Phaser phaser;

    public Player(Phaser phaser) {
        this.phaser = phaser;
    }

    @Override
    public void run() {
        try {
        	// 随机模拟到场时间
            TimeUnit.SECONDS.sleep((new Random().nextInt(5)));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("选手-"+Thread.currentThread().getName()+":已到达赛场");
        // 标记阶段,到达某阶段并等待其他线程
        phaser.arriveAndAwaitAdvance();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("选手-"+Thread.currentThread().getName()+":已开始比赛");
        phaser.arriveAndAwaitAdvance();

        try {
            TimeUnit.SECONDS.sleep((new Random().nextInt(5)));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("选手-"+Thread.currentThread().getName()+":已完成比赛");
        phaser.arriveAndAwaitAdvance();
    }
}

3、测试

package java7.thread.chapter2.test1;


/**
 * 并发工具类Phaser例子
 * (CountDownLatch:await()阻塞,等待计数器减为0时运行,调用countDown()计数器减一)
 * (CyclicBarrier:当拦截了n个线程时,await(),这n个线程一起运行。为达到n个之前,被拦截的线程都被阻塞)
 * (Semaphore信号量:流量控制,访问某资源的线程不超过多少个,超过的阻塞。acquire()  release())
 * (Exchanger:交换2个线程的数据,一对一的生产消费)
 */
public class Main {
    public static void main(String[] args) {
    	// 几个线程所属的Phaser对象,通过构造注入
        MyPhaser myPhaser = new MyPhaser();

        for (int i = 0; i < 5; i++) {
            // 新建线程并注册到Phaser
            new Thread(new Player(myPhaser)).start();
            myPhaser.register();
        }

        // 当myPhaser所有阶段都已完成,主线程才继续往下运行,打印比赛结束
        while (!myPhaser.isTerminated()) {

        }

        System.err.println("==比赛结束==");
    }
}

运行结果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值