25-案例实现
案例实现
根据如下步骤实现本案例。
1.创建一个名为 MyPhaser
的类,并继承 Phaser
类:
public class MyPhaser extends Phaser {
2.重写 onAdvance()
方法。通过判断参数 phase
的值来调用不同的辅助方法:如果 phase
的值等于0,则调用 studentsArrived()
方法;如果 phase
的值等于1,则调用 finishFirstExercise()
方法;如果 phase
的值等于2,则调用 finishSecondExercise()
方法;如果 phase
的值等于3,则调用 finishExam()
方法;否则,返回 true
,这表示 Phaser
对象被终止:
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
return studentsArrived();
case 1:
return finishFirstExercise();
case 2:
return finishSecondExercise();
case 3:
return finishExam();
default:
return true;
}
}
3.实现辅助方法 studentsArrived()。
该方法向控制台输出两条相关的日志信息并且返回 false
,这表明 Phaser
对象将继续执行:
private boolean studentsArrived() {
System.out.printf("Phaser: The exam are going to start.
The students are ready.\n");
System.out.printf("Phaser: We have %d students.\n",
getRegisteredParties());
return false;
}
4.实现辅助方法 finishFirstExercise()
。该方法向控制台输出两条相关的日志信息并且返回 false
,这表明 Phaser
对象将继续执行:
private boolean finishFirstExercise() {
System.out.printf("Phaser: All the students has finished the
first exercise.\n");
System.out.printf("Phaser: It's turn for the second one.\n");
return false;
}
5.实现辅助方法 finishSecondExercise()
。该方法向控制台输出两条相关的日志信息并且返回 false
,这表明 Phaser
对象将继续执行:
private boolean finishSecondExercise() {
System.out.printf("Phaser: All the students has finished the
first exercise.\n");
System.out.printf("Phaser: It's turn for the third one.\n");
return false;
}
6.实现辅助方法 finishExam()
。该方法向控制台输出两条相关的日志信息并且返回 true
,这表明 Phaser
对象将结束其工作:
private boolean finishExam() {
System.out.printf("Phaser: All the students has finished
the exam.\n");
System.out.printf("Phaser: Thank you for your time.\n");
return true;
}
7.创建一个名为 Student
的类,并实现 Runnable
接口。该类用来模拟参与考试的学生:
public class Student implements Runnable {
8.声明一个名为 phaser
的 Phaser
类型对象:
private Phaser phaser;
9.实现该类的构造器,完成 Phaser
对象的初始化:
public Student(Phaser phaser) {
this.phaser=phaser;
}
10.实现 run()
方法,用来模拟考试过程:
@Override
public void run() {
11.首先,向控制台输出一条消息表明该考生已到达考场,调用 Phaser
对象的 arriveAndAwaitAdvance()
方法来等待其他线程:
System.out.printf("%s: Has arrived to do the exam. %s\n",
Thread.currentThread().getName(),new Date());
phaser.arriveAndAwaitAdvance();
12.向控制台输出一条信息并调用私有的 doExercise1()
方法,用来模拟回答第一道考题。答题结束后,向控制台输出另一条信息并调用 Phaser
对象的 arriveAndAwaitAdvance()
方法,等待其他同学完成第一道考题:
System.out.printf("%s: Is going to do the first exercise.%s\n",
Thread.currentThread().getName(),new Date());
doExercise1();
System.out.printf("%s: Has done the first exercise.%s\n",
Thread.currentThread().getName(),new Date());
phaser.arriveAndAwaitAdvance();
13.第二道考题和第三道考题的答题过程与第一道考题相同:
System.out.printf("%s: Is going to do the second exercise.
%s\n",Thread.currentThread().getName(),
new Date());
doExercise2();
System.out.printf("%s: Has done the second exercise.%s\n",
Thread.currentThread().getName(),new Date());
phaser.arriveAndAwaitAdvance();
System.out.printf("%s: Is going to do the third exercise.%s\n",
Thread.currentThread().getName(),new Date());
doExercise3();
System.out.printf("%s: Has finished the exam.%s\n",
Thread.currentThread().getName(),new Date());
phaser.arriveAndAwaitAdvance();
14.实现辅助方法 doExercise1()
。调用该方法的线程将休眠一段随机时间,用于模拟答题耗时:
private void doExercise1() {
try {
Long duration=(long)(Math.random()*10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
15.实现辅助方法 doExercise2()
。调用该方法的线程将休眠一段随机时间,用于模拟答题耗时:
private void doExercise2() {
try {
Long duration=(long)(Math.random()*10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
16.实现辅助方法 doExercise3()
。调用该方法的线程将休眠一段随机时间,用于模拟答题耗时:
private void doExercise3() {
try {
Long duration=(long)(Math.random()*10);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
17.实现案例主程序的入口 main()
方法:
public class Main {
public static void main(String[] args) {
18.创建一个 MyPhaser
对象:
MyPhaser phaser=new MyPhaser();
19.创建5个 Student
对象,并且通过 phaser
对象的 register()
方法对该对象进行注册:
Student students[]=new Student[5];
for (int i=0; i<students.length; i++){
students[i]=new Student(phaser);
phaser.register();
}
20.创建并启动5个线程运行学生任务:
Thread threads[]=new Thread[students.length];
for (int i=0; i<students.length; i++) {
threads[i]=new Thread(students[i],"Student "+i);
threads[i].start();
}
21.等待5个线程运行结束:
for (int i=0; i<threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
22.使用 isTerminated()方
法,向控制台输出 phaser
独享的终止状态:
System.out.printf("Main: The phaser has finished: %s.\n",
phaser.isTerminated());