并发编程:线程同步工具:4、Phaser(onAdvance方法) 阶段性并发任务中阶段转变的控制

目录

Phaser的onAdvance方法

案例说明

一、主程序

二、学生类(答题)

三、自定义的MyPhaser

四、执行结果


Phaser的onAdvance方法

在阶段转变时,即上一阶段结束后,下一阶段开始前,会自动调用onAdvance方法。如果阶段继续执行则返回false,如果Phaser准备进入终止状态,则返回true。

Phaser原逻辑是判断 参与者数量==0。但我们也可以继承Phaser类,通过重写onAdvance方法来自定义相关的控制以及额外的逻辑。

案例说明

案例模拟一场考试,它分3轮答题,每轮答题都需要等待所有学生完成上一轮的问题才开始进行。

一、主程序

程序创建了5个学生,参与答题。

package xyz.jangle.thread.test.n3_6.phaser;

import java.util.concurrent.Phaser;

/**
 * 	Phaser DEMO,本案例模拟一场考试。
 * 	它总共进行3轮答题,每一轮都要等所有学生答题完成后,再进入下一轮答题。
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月12日 下午4:06:42
 * 
 */
public class M {

	public static void main(String[] args) {
		Phaser phaser = new MyPhaser();
		Student[] students = new Student[5];
		for (int i = 0; i < students.length; i++) {
			students[i] = new Student(phaser);
			phaser.register();
		}
		Thread[] threads = new Thread[students.length];
		for (int i = 0; i < threads.length; i++) {
			threads[i] = new Thread(students[i]);
			threads[i].start();
		}
		for (int i = 0; i < threads.length; i++) {
			try {
				threads[i].join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Main: 考试结束 phaser终止:"+phaser.isTerminated());

	}

}

二、学生类(答题)

模拟考试答题,通过phaser进行每一轮的同步。

package xyz.jangle.thread.test.n3_6.phaser;

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

/**
 * 	创建学生类,模拟考试答题,通过phaser进行每一轮的同步。
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月12日 下午3:53:17
 * 
 */
public class Student implements Runnable {

	private Phaser phaser;

	public Student(Phaser phaser) {
		super();
		this.phaser = phaser;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ",抵达考场," + new Date());
		phaser.arriveAndAwaitAdvance();
		System.out.println(Thread.currentThread().getName() + ",进行第一轮答题" + new Date());
		doExercise1();
		System.out.println(Thread.currentThread().getName() + ",完成第一轮答题,等待大家答完" + new Date());
		phaser.arriveAndAwaitAdvance();
		System.out.println(Thread.currentThread().getName() + ",开始第二轮答题" + new Date());
		doExercise2();
		System.out.println(Thread.currentThread().getName() + ",完成第二轮答题,等待大家答完" + new Date());
		phaser.arriveAndAwaitAdvance();
		System.out.println(Thread.currentThread().getName() + ",开始第三轮答题" + new Date());
		doExericise3();
		System.out.println(Thread.currentThread().getName() + ",完成第三轮答题,等待大家答完" + new Date());
		phaser.arriveAndAwaitAdvance();

	}

	private void doExericise3() {
		doExercise1();
	}

	private void doExercise2() {
		doExercise1();
	}

	private void doExercise1() {
		try {
			TimeUnit.SECONDS.sleep((long) (Math.random() * 10));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

}

三、自定义的MyPhaser

继承自Phaser,并重写onAdvance方法,实现自定义的干预。

package xyz.jangle.thread.test.n3_6.phaser;

import java.util.concurrent.Phaser;

/**
 * 	继承Phaser,重写onAdvance方法,进行自定义操作。
 * 	(自定义每个阶段转变时所要进行的干预动作。例:阶段1完成后 -> 阶段2开始前)
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年8月12日 下午3:27:58
 * 
 */
public class MyPhaser extends Phaser {

	@Override
	protected boolean onAdvance(int phase, int registeredParties) {
		// 此处如果返回true会让phaser进入终止状态。
		switch (phase) {
		case 0:
			return studentsArrived();
		case 1:
			return finishFirstExercise();
		case 2:
			return finishSecondExercise();
		case 3:
			return finishExam();
		default:
			return true;
		}
	}

	private boolean finishExam() {
		System.out.println("第三轮答题结束,考试结束。");
		return true;
	}

	private boolean finishSecondExercise() {
		System.out.println("所有学生完成第二轮答题,准备进入第三轮答题。");
		return false;
	}

	private boolean finishFirstExercise() {
		System.out.println("所有学生完成第一轮答题。准备进入第二轮答题。");
		return false;
	}

	private boolean studentsArrived() {
		System.out.println("学生全部抵达考场,学生人数"+getRegisteredParties()+"人");
		return false;
	}
	
	

}

四、执行结果

Thread-2,抵达考场,Wed Aug 12 16:14:02 CST 2020
Thread-1,抵达考场,Wed Aug 12 16:14:02 CST 2020
Thread-4,抵达考场,Wed Aug 12 16:14:02 CST 2020
Thread-0,抵达考场,Wed Aug 12 16:14:02 CST 2020
Thread-3,抵达考场,Wed Aug 12 16:14:02 CST 2020
学生全部抵达考场,学生人数5人
Thread-3,进行第一轮答题Wed Aug 12 16:14:02 CST 2020
Thread-1,进行第一轮答题Wed Aug 12 16:14:02 CST 2020
Thread-2,进行第一轮答题Wed Aug 12 16:14:02 CST 2020
Thread-0,进行第一轮答题Wed Aug 12 16:14:02 CST 2020
Thread-4,进行第一轮答题Wed Aug 12 16:14:02 CST 2020
Thread-2,完成第一轮答题,等待大家答完Wed Aug 12 16:14:08 CST 2020
Thread-1,完成第一轮答题,等待大家答完Wed Aug 12 16:14:09 CST 2020
Thread-4,完成第一轮答题,等待大家答完Wed Aug 12 16:14:10 CST 2020
Thread-3,完成第一轮答题,等待大家答完Wed Aug 12 16:14:10 CST 2020
Thread-0,完成第一轮答题,等待大家答完Wed Aug 12 16:14:10 CST 2020
所有学生完成第一轮答题。准备进入第二轮答题。
Thread-0,开始第二轮答题Wed Aug 12 16:14:10 CST 2020
Thread-3,开始第二轮答题Wed Aug 12 16:14:10 CST 2020
Thread-1,开始第二轮答题Wed Aug 12 16:14:10 CST 2020
Thread-2,开始第二轮答题Wed Aug 12 16:14:10 CST 2020
Thread-4,开始第二轮答题Wed Aug 12 16:14:10 CST 2020
Thread-3,完成第二轮答题,等待大家答完Wed Aug 12 16:14:11 CST 2020
Thread-4,完成第二轮答题,等待大家答完Wed Aug 12 16:14:11 CST 2020
Thread-2,完成第二轮答题,等待大家答完Wed Aug 12 16:14:18 CST 2020
Thread-0,完成第二轮答题,等待大家答完Wed Aug 12 16:14:19 CST 2020
Thread-1,完成第二轮答题,等待大家答完Wed Aug 12 16:14:19 CST 2020
所有学生完成第二轮答题,准备进入第三轮答题。
Thread-1,开始第三轮答题Wed Aug 12 16:14:19 CST 2020
Thread-4,开始第三轮答题Wed Aug 12 16:14:19 CST 2020
Thread-2,开始第三轮答题Wed Aug 12 16:14:19 CST 2020
Thread-0,开始第三轮答题Wed Aug 12 16:14:19 CST 2020
Thread-3,开始第三轮答题Wed Aug 12 16:14:19 CST 2020
Thread-2,完成第三轮答题,等待大家答完Wed Aug 12 16:14:19 CST 2020
Thread-4,完成第三轮答题,等待大家答完Wed Aug 12 16:14:19 CST 2020
Thread-1,完成第三轮答题,等待大家答完Wed Aug 12 16:14:22 CST 2020
Thread-3,完成第三轮答题,等待大家答完Wed Aug 12 16:14:27 CST 2020
Thread-0,完成第三轮答题,等待大家答完Wed Aug 12 16:14:28 CST 2020
第三轮答题结束,考试结束。
Main: 考试结束 phaser终止:true

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值