多线程设计模式(1)—— Future 设计模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AnselLyy/article/details/80958377

Future 设计模式

欢迎访问 我的个人博客

概述

Future模式有点类似于商品订单。在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直持续等待直到这个答复收到之后再去做别的事情,但如果利用Future模式,其调用方式改为异步,而原先等待返回的时间段,在主调用函数中,则可以用于处理其他事务。

Future模式的主要参与者

参与者 作用
Main 系统启动,调用Client发出请求
Client 返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData
Data 返回数据的接口
FutureData Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData
RealData 真实数据,其构造是比较慢的

JDK 内置的 Future 模式

由于Future是非常常用的多线程设计模式,因此在JDK中内置了Future模式的实现。
这些类在java.util.concurrent包里面。其中最为重要的是FutureTask类,它实现了Runnable接口,作为单独的线程运行。在其run()方法中,通过Sync内部类调用Callable接口,并维护Callable接口的返回对象。当使用FutureTask.get()方法时,将返回Callable接口的返回对象。

Future 接口提供的线程控制功能

boolean cancle(boolean mayInterruptIfRunning);  // 取消任务
boolean isCancelled();  // 是否已经取消
boolean isDone();    // 是否已经完成
V get() throws InterruptedException, ExecutionException;  //取得返回对象
V get(long timeout, TimeUnit unit);  //取得返回对象,可以设置超时时间

Future 模式案例

public class FutureMode implements Callable<String> {

    private String param;

    public FutureMode(String param) {
        // TODO Auto-generated constructor stub
        this.param = param;
    }

    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        StringBuffer stringBuffer = new StringBuffer();

        for (int i = 0; i < 10; i++) {
            stringBuffer.append(param);

            // 通过 sleep 来模拟真实情况下的业务缓慢
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        return stringBuffer.toString();
    }

    public static void main(String[] args) {

        FutureTask<String> futureTask = new FutureTask<>(new FutureMode("test"));

        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.submit(futureTask);
        System.out.println("请求完毕");

        try {

            // 模拟其他的业务操作
            Thread.sleep(2000);

            System.out.println("数据 = " + futureTask.get());
        } catch (InterruptedException | ExecutionException e) {
            // TODO: handle exception
        } finally {
            executorService.shutdown();
        }

    }

}

猜你喜欢

转载自blog.csdn.net/AnselLyy/article/details/80958377