phaser java_Java并发编程之Phaser类

Phaser这个类的使用场景为N个线程分阶段并行的问题。有这么一个任务为“做3道题“,每个学生一个进程,5个学生可以并行做,这个就是常规的并发,但是如果加一个额外的 限制条件,必须等所有人都做完类第一题,才能开始做第二题,必须等所有人都做完了第二题,才能做第三题,这个问题就转变成了分阶段并发的问题,最适合用Phaser来解题,下面给出源代码,大家可以自己尝试:

MyPhaser.java

import java.util.concurrent.Phaser;

public class MyPhaser extends Phaser {

@Override

protected boolean onAdvance(int phase, int registeredParties) { //在每个阶段执行完成后回调的方法

switch (phase) {

case 0:

return studentArrived();

case 1:

return finishFirstExercise();

case 2:

return finishSecondExercise();

case 3:

return finishExam();

default:

return true;

}

}

private boolean studentArrived(){

System.out.println("学生准备好了,学生人数:"+getRegisteredParties());

return false;

}

private boolean finishFirstExercise(){

System.out.println("第一题所有学生做完");

return false;

}

private boolean finishSecondExercise(){

System.out.println("第二题所有学生做完");

return false;

}

private boolean finishExam(){

System.out.println("第三题所有学生做完,结束考试");

return true;

}

}

StudentTask.java

import java.util.concurrent.Phaser;

import java.util.concurrent.TimeUnit;

public class StudentTask implements Runnable {

private Phaser phaser;

public StudentTask(Phaser phaser) {

this.phaser = phaser;

}

@Override

public void run() {

System.out.println(Thread.currentThread().getName()+"到达考试");

phaser.arriveAndAwaitAdvance();

System.out.println(Thread.currentThread().getName()+"做第1题时间...");

doExercise1();

System.out.println(Thread.currentThread().getName()+"做第1题完成...");

phaser.arriveAndAwaitAdvance();

System.out.println(Thread.currentThread().getName()+"做第2题时间...");

doExercise2();

System.out.println(Thread.currentThread().getName()+"做第2题完成...");

phaser.arriveAndAwaitAdvance();

System.out.println(Thread.currentThread().getName()+"做第3题时间...");

doExercise3();

System.out.println(Thread.currentThread().getName()+"做第3题完成...");

phaser.arriveAndAwaitAdvance();

}

private void doExercise1() {

long duration = (long)(Math.random()*10);

try {

TimeUnit.SECONDS.sleep(duration);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

private void doExercise2() {

long duration = (long)(Math.random()*10);

try {

TimeUnit.SECONDS.sleep(duration);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

private void doExercise3() {

long duration = (long)(Math.random()*10);

try {

TimeUnit.SECONDS.sleep(duration);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

Main.java

public class Main {

public static void main(String[] args) {

MyPhaser phaser = new MyPhaser();

StudentTask[] studentTask = new StudentTask[5];

for (int i = 0; i < studentTask.length; i++) {

studentTask[i] = new StudentTask(phaser);

phaser.register(); //注册一次表示phaser维护的线程个数

}

Thread[] threads = new Thread[studentTask.length];

for (int i = 0; i < studentTask.length; i++) {

threads[i] = new Thread(studentTask[i], "Student "+i);

threads[i].start();

}

//等待所有线程执行结束

for (int i = 0; i < studentTask.length; i++) {

try {

threads[i].join();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("Phaser has finished:"+phaser.isTerminated());

}

}

注意这里的arriveAndAwaitAdvance方法,

可以拆分成两个方法:arrive(), awaitAdvance, 拆分的目的是可以在这两个方法之间插入一些额外的代码构造一个叫fuzzy barrier的概念,增加程序的并发性(程序和barrier的并发),来看一段解释:

945ded72e0551b64a21688bdb0cb97d4.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值