java同步工具Phaser

int32位 posted @ Sep 06, 2014 11:13:13 AM in java , 3730 阅读
转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!

从java7开始在concurrent包中加入了Phaser类,它几乎可以取代CountDownLatch和CyclicBarrier, 其功能更灵活,更强大,支持动态调整需要控制的线程数。下面以一个具体实例说明这个Phaser类的用处,相信理解这个例子后,其功能不言而喻。

例子:有若干考生参加考试,考试科目是统一的,考试顺序为语文、数学、英语共三门,若其中一门挂科,则不能参加后面的考试。现在假设考试时间不受限制,开考时间以最后一名考完上一科时间为准,即先考完的考生并且成绩合格,需要参加下一门考试,则必须等待所有考生考完当科。

import java.util.*;
import java.util.concurrent.*;
class Examinee implements Runnable {
    public static Random random = new Random(new Date().getTime());
    private String name;
    private Phaser phaser;
    private int english;
    private int chinese;
    private int math;
    public Examinee(String name, Phaser phaser) {
        this.name = name;
        this.phaser = phaser;
    }
    public boolean english() {
        int time = random.nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(time); /* 考试时间是一个随机数 */
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        english = random.nextInt(101) ; /* 假定考试成绩是随机的 */
        if (english < 60) {
            System.out.printf("%s Failed to pass English!\n", name);
            phaser.arriveAndDeregister(); /* 考试不合格,取消考试资格 */
            return false;
        } else {
            phaser.arriveAndAwaitAdvance(); /* 通过考试,可以进行下一门考试 */
            return true;
        }
    }
    public boolean chinese() {
        int time = random.nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        chinese = random.nextInt(101) ;
        if (chinese < 60) {
            System.out.printf("%s Failed to pass Chinese!\n", name);
            phaser.arriveAndDeregister();
            return false;
        } else {
            phaser.arriveAndAwaitAdvance();
            return true;
        }
    }
    public boolean math() {
        int time = random.nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(time);
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        math = random.nextInt(101) ;
        if (math < 60) {
            System.out.printf("%s Failed to pass Math!\n", name);
            phaser.arriveAndDeregister();
            return false;
        } else {
            phaser.arriveAndAwaitAdvance();
            return true;
        }
    }
    public void showInfo() {
        System.out.printf("%s\tChinese:%d\tEnglish:%d\tMath:%d\n", name, chinese, english, math);
        phaser.arriveAndDeregister();
    }
    @Override
    public void run() {
        phaser.arriveAndAwaitAdvance(); /* 等待考生做好准备,即在同一个起跑线上 */
        System.out.printf("%s is ready!\n", name);
        if (!chinese() || !english() || !math())
            return;
        showInfo(); /* 只显示所有科目均合格的考生分数 */
    }
}
public class PhaserDemo2 {
    public static void main(String[] args) {
        final String[] names = {"Jim", "Hary", "Mary", "Jhon", "Ali", "Lucy", "Wang", "Zhang", "Li", "Uhm", "Hey", "Gu", "Asu", "Who"};
        Phaser phaser = new Phaser(names.length);
        List<Thread> threads = new ArrayList<>(names.length);
        for (String name : names) {
            threads.add(new Thread(new Examinee(name, phaser), name)); /* 创建各个考生线程 */
        } 
        for (Thread t : threads) {
            t.start(); /* 开始考试 */
        }
        for (Thread t : threads) {
            try {
                t.join(); /* 等待考试结束 */
            } catch (InterruptedException e) {
                e.printStackTrace(System.err);
            }
        }
        System.out.printf("Terminal ? %s\n", phaser.isTerminated());
    }
}

由上面的例子,可以看出Phaser的功能。其中arrive方法很像CountDownLatch的countDown方法和CyclicBarrier的await方法,请自行比较之!Phaser类还有很多其他的功能,可以查看其API文档。

转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!
  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter