当前位置:嗨网首页>书籍在线阅读

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.声明一个名为 phaserPhaser 类型对象:

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());