Promise模式

Promise 模式

简介

Promise 模式是一种异步编程模式,使用它我们可以先开始一个任务, 并能立即获取这个任务的执行结果的凭证对象, 而不需要等待任务执行完毕,就可以继续执行其他操作. 当需要执行结果的时候,可以通过凭证对象,可以调用相应方法来获取.

这样操作的好处就是: 避免了不必要的等待, 增强系统的并发性.

成员

  1. 任务执行器
  2. 凭证对象
  3. 自定义任务
  4. 任务结果对象

实例实现

  • 模拟任务 - MyTask
public class MyTask implements Callable<MyPromiseResult> {

    private String context;

    public MyTask(String context) {
        this.context = context;
    }

    @Override
    public MyPromiseResult call() throws Exception {

        Random random = new Random();
        int workTime = random.nextInt(5 * 1000);

        MyPromiseResult result = new MyPromiseResult(workTime, context);
        result.setTaskStartTime();

        Thread.sleep(workTime);// 模拟工作

        result.setTaskEndTime();

        return result;
    }

}
  • 凭证对象使用: FutureTask
  • 凭证返回结果: MyPromiseResult

public class MyPromiseResult {
    // 任务开始时间
    private long taskStartTime;
    // 任务结束时间
    private long taskEndTime;
    //  工作耗时间
    private final int workTime;
    // 上下文任务名称
    private final String taskName ;

    public MyPromiseResult (int workTime, final String taskName) {
        this.workTime = workTime;
        this.taskName = taskName;
    }

    public void setTaskStartTime() {
        this.taskStartTime = System.currentTimeMillis();
    }

    public void setTaskEndTime() {
        this.taskEndTime = System.currentTimeMillis();
    }

    public long getTaskStartTime() {
        return this.taskStartTime;
    }

    public long getTaskEndTime() {
        return this.taskEndTime;
    }


    public String getTaskName() {
        return taskName;
    }

    public void print() {
        if (taskEndTime > 0) { // 代表完成
            System.out.println("完成任务名称:" + taskName +"...开始时间" + taskStartTime +"...耗时间:"
                    + workTime);
        }
    }

}
  • 测试类

public class PromiseTester {
    // 任务执行器
    static ThreadPoolExecutor threadExecutor = null;

    static {
        threadExecutor = new ThreadPoolExecutor(2, Runtime.getRuntime().availableProcessors() * 2 , 
                60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
                new ThreadFactory() {

                    @Override
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setDaemon(true);
                        return t;
                    }
                });
    }

    public static void main(String args[]) throws InterruptedException, ExecutionException {
        test();
    }

    /**
     * 
     *  测试有一个任务它由10个子任务构成, 每个子任务相互独立
     *  只有10个子任务都完成,这个任务才算完成 
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static void test() throws InterruptedException, ExecutionException {
        ConcurrentMap<String, FutureTask<MyPromiseResult>>  taskMap = new ConcurrentHashMap<String, 
                FutureTask<MyPromiseResult>>();

        for (int i = 0; i < 10; i ++) {
            String name = "task-" + i;
            FutureTask<MyPromiseResult> futureTask = PromiseTester.execute(name);
            taskMap.put(name, futureTask);
        }

        FutureTask<MyPromiseResult> task = null;
        MyPromiseResult myPromiseResult;

        // 轮询判断任务是否完成

        for (;;) {

            if (!taskMap.isEmpty()) {

                Iterator<String> iterator = taskMap.keySet().iterator();

                while (iterator.hasNext()) {
                    task = taskMap.get(iterator.next());
                    if (null != task && task.isDone()) {
                        myPromiseResult = task.get();
                        myPromiseResult.print();

                        taskMap.remove(myPromiseResult.getTaskName());
                        iterator = taskMap.keySet().iterator();
                    }
                }

            } else {
                break;
            }

            Thread.sleep(10);

        }

        System.out.println("############所有任务完成###############");

    }

    /**
     * 异步提交,并获取凭证对象
     * 
     * @param context
     * @return
     */
    public static FutureTask<MyPromiseResult> execute(String context) {
        FutureTask<MyPromiseResult> futureTask = new FutureTask<MyPromiseResult>(new MyTask(context));

        threadExecutor.execute(futureTask);

        return futureTask;
    }


}
  • 测试结果
完成任务名称:task-0...开始时间1471786979890...耗时间:352
完成任务名称:task-1...开始时间1471786979890...耗时间:1526
完成任务名称:task-3...开始时间1471786981416...耗时间:1835
完成任务名称:task-2...开始时间1471786980242...耗时间:4534
完成任务名称:task-4...开始时间1471786983251...耗时间:3672
完成任务名称:task-5...开始时间1471786984776...耗时间:3908
完成任务名称:task-6...开始时间1471786986923...耗时间:2037
完成任务名称:task-7...开始时间1471786988684...耗时间:2948
完成任务名称:task-9...开始时间1471786991632...耗时间:238
完成任务名称:task-8...开始时间1471786988960...耗时间:3923
############所有任务完成###############
发布了49 篇原创文章 · 获赞 13 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章