Java并发编程中级篇(六):并发阶段性任务执行阶段切换过程

Phaser类提供了一个onAdvance(),这个方法接收两个int类型参数:分别是当前执行阶段数以及注册的参与者数量。方法返回一个布尔值,若是返回false代表Phaser中还有任务在执行,返回true表示这一阶段Phaser执行完毕。java

Phaser对象进行阶段切换的时候,在全部在arriveAndAwaitAdvance()方法里休眠线程被唤醒以前,onAdvance()方法将被自动调用。onAdvance()方法返回布尔值代表Phaser终止与否,false表示没有终止,于是县城能够继续执行其余阶段。若是返回true,则Phaser仍然唤醒等待的线程,可是状态已经改变为终止状态,因此继续调用phaser的方法将当即返回,而且isTermination()方法也将返回true。并发

这个方法的默认实现以下,若是参与者数量是0返回true,不然返回false。可是咱们能够经过继承Phaser类类覆盖这个方法。当从一个阶段切换到另外一个阶段是须要作一些操做,那么咱们就这么作。dom

protected boolean onAdvance(int phase, int registeredParties) {
  return registeredParties == 0;
}

咱们实现一个学生参加考试的例子,须要等待全部学生都到齐后才能参加考试,每一个学生都参加三场考试,而后考试结束。ide

首先咱们实现本身的Phaser类MyPhaser,这个类中咱们重写onAdvance()方法,并定义每次阶段切换执行的代码。开始打印考试开始参加学生的数量,而后打印第一场考试结束信息,接着打印第二场考试结束信息,最后打印考试结束信息。前三个方法返回false,代表Phaser还在执行,最后一个方法返回true,代表Phaser执行结束。this

public class MyPhaser extends Phaser {
    @Override
    protected boolean onAdvance(int phase, int registeredParties) {
        switch (phase) {
            case 0:
                return studentsArrived();
            case 1:
                return finishFirstExercies();
            case 2:
                return finishSecondExercies();
            case 3:
                return finishExam();
            default:
                return true;
        }
    }

    private boolean studentsArrived() {
        System.out.printf("Phaser: The exam are going to start. The %d students are ready.\n",
                getRegisteredParties());
        return false;
    }

    private boolean finishFirstExercies() {
        System.out.printf("Phaser: All the studnets have finished the first exercies.\n");
        return false;
    }

    private boolean finishSecondExercies() {
        System.out.printf("Phaser: All the students have finished the second exercies.\n");
        return false;
    }

    private boolean finishExam() {
        System.out.printf("Phaser: All the students have finished the exam.\n");
        return true;
    }

}

定义Student类,使用phaser模拟四步操做 ,分别是考生到场,第一场考试,第二场考试,第三场考试。线程

public class Student implements Runnable{
    private Phaser phaser;

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

    @Override
    public void run() {
        System.out.printf("%s: Has arrived to the exam. %s\n", Thread.currentThread().getName(), new Date());
        phaser.arriveAndAwaitAdvance();
        System.out.printf("%s: is going to do the first exercise.\n", Thread.currentThread().getName());
        doExercise1();
        System.out.printf("%s: has done the first exercise.\n", Thread.currentThread().getName());
        phaser.arriveAndAwaitAdvance();
        System.out.printf("%s: is going to do the second exercise.\n", Thread.currentThread().getName());
        doExercise2();
        System.out.printf("%s: has done the second exercise.\n", Thread.currentThread().getName());
        phaser.arriveAndAwaitAdvance();
        System.out.printf("%s: is going to do the third exercise.\n", Thread.currentThread().getName());
        doExercise3();
        System.out.printf("%s: has finished the exam.\n", Thread.currentThread().getName());
        phaser.arriveAndAwaitAdvance();
    }

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

    private void doExercise2() {
        long duration = (long)(Math.random() * 20);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void doExercise3() {
        long duration = (long)(Math.random() * 20);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

实现主方法类,在这里咱们建立5个考生线程,并启动它们。咱们并无在Phaser初始化的时候指定并发线程数量,而是在建立线程的时候使用register()方法来注册到Phaser上。日志

public class Main{
    public static void main(String[] args) {
        Phaser phaser = new MyPhaser();

        Student[] students = new Student[5];
        Thread[] threads = new Thread[5];

        for (int i = 0; i < 5; i++) {
            students[i] = new Student(phaser);
            phaser.register();
            threads[i] = new Thread(students[i], "Student-" + i);
        }

        for (int i = 0; i < 5; i++) {
            threads[i].start();
        }

        for (int i = 0; i < 5; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.printf("Main: The phaser has finished: %s.\n", phaser.isTerminated());
    }
}

查看日志code

Student-4: Has arrived to the exam. Sat Nov 26 19:51:06 CST 2016
Student-0: Has arrived to the exam. Sat Nov 26 19:51:06 CST 2016
Student-2: Has arrived to the exam. Sat Nov 26 19:51:06 CST 2016
Student-1: Has arrived to the exam. Sat Nov 26 19:51:06 CST 2016
Student-3: Has arrived to the exam. Sat Nov 26 19:51:06 CST 2016
Phaser: The exam are going to start. The 5 students are ready.
Student-3: is going to do the first exercise.
Student-0: is going to do the first exercise.
Student-0: has done the first exercise.
Student-4: is going to do the first exercise.
Student-2: is going to do the first exercise.
Student-1: is going to do the first exercise.
Student-1: has done the first exercise.
Student-4: has done the first exercise.
Student-3: has done the first exercise.
Student-2: has done the first exercise.
Phaser: All the studnets have finished the first exercies.
Student-2: is going to do the second exercise.
Student-0: is going to do the second exercise.
Student-4: is going to do the second exercise.
Student-1: is going to do the second exercise.
Student-1: has done the second exercise.
Student-3: is going to do the second exercise.
Student-2: has done the second exercise.
Student-0: has done the second exercise.
Student-4: has done the second exercise.
Student-3: has done the second exercise.
Phaser: All the students have finished the second exercies.
Student-3: is going to do the third exercise.
Student-2: is going to do the third exercise.
Student-1: is going to do the third exercise.
Student-0: is going to do the third exercise.
Student-4: is going to do the third exercise.
Student-4: has finished the exam.
Student-0: has finished the exam.
Student-2: has finished the exam.
Student-1: has finished the exam.
Student-3: has finished the exam.
Phaser: All the students have finished the exam.
Main: The phaser has finished: true.

咱们尝试把第一场考试执行完毕后的onAdvance方法返回值改成true试试结果,能够看到全部线程执行完第二场考试以后直接就开始执行第三场考试了,并无等待其余线程都执行完毕第二场考试。对象

Student-4: Has arrived to the exam. Sat Nov 26 19:46:25 CST 2016
Student-3: Has arrived to the exam. Sat Nov 26 19:46:25 CST 2016
Student-1: Has arrived to the exam. Sat Nov 26 19:46:25 CST 2016
Student-2: Has arrived to the exam. Sat Nov 26 19:46:25 CST 2016
Student-0: Has arrived to the exam. Sat Nov 26 19:46:25 CST 2016
Phaser: The exam are going to start. The 5 students are ready.
Student-0: is going to do the first exercise.
Student-2: is going to do the first exercise.
Student-4: is going to do the first exercise.
Student-3: is going to do the first exercise.
Student-1: is going to do the first exercise.
Student-1: has done the first exercise.
Student-0: has done the first exercise.
Student-2: has done the first exercise.
Student-4: has done the first exercise.
Student-3: has done the first exercise.
Phaser: All the studnets have finished the first exercies.
Student-3: is going to do the second exercise.
Student-2: is going to do the second exercise.
Student-0: is going to do the second exercise.
Student-1: is going to do the second exercise.
Student-4: is going to do the second exercise.
Student-3: has done the second exercise.
Student-3: is going to do the third exercise.
Student-1: has done the second exercise.
Student-1: is going to do the third exercise.
Student-0: has done the second exercise.
Student-0: is going to do the third exercise.
Student-0: has finished the exam.
Student-2: has done the second exercise.
Student-2: is going to do the third exercise.
Student-4: has done the second exercise.
Student-4: is going to do the third exercise.
Student-3: has finished the exam.
Student-2: has finished the exam.
Student-1: has finished the exam.
Student-4: has finished the exam.
Main: The phaser has finished: true.
相关文章
相关标签/搜索