《图解Java多线程设计模式》之十:Future模式

一,Future模式

假设有一个方法需要花费很长的时间才能获取运行结果。那么,与其一直等待结果,不如先拿一张 提货单。获取提货单并不耗费时间。这里提货单就称为Future角色
获取Future角色的线程会在稍后使用Future角色来获取运行结果
在处理开始时先返回Future角色,等到其他线程出来终止后,在将结果设置到Future角色中。
二,示例程序

Data:访问数据的接口

RealData:实际处理数据的类

FutureData:表示RealData的提货单,

Host:先拿提货单future实例,开启新线程创建RealData实例

public interface Data {

    public abstract String getContent();
}
public class RealData implements Data {
    private final String content;

    public RealData(int count,char c){
        System.out.println("   making RealData("+count+" , "+ c +") begin");
        char[] buffer = new char[count];
        for (int i = 0; i <count ; i++) {
            buffer[i] = c ;
            try {
                Thread.sleep(100);
            }catch (InterruptedException e){

            }
        }
        System.out.println("   making RealData("+count+" , "+ c +") end");
        this.content = new String(buffer);
    }
    @Override
    public String getContent() {

        return content;
    }

    @Override
    public String toString() {
        return "real.toString";
    }
}
public class FutureData implements Data {
    private RealData realData = null;

    private boolean ready = false;

    /**
     * 为Future类中的字段设置值
     * @param realData
     */
    public synchronized void setRealData(RealData realData) {
        if(ready){
            return;
        }
        this.realData = realData;
        this.ready = true;
        notifyAll();
    }

    /**
     * 还没有成功设置值之前 一直等待。设置成功后就返回值
     * @return
     */
    @Override
    public synchronized String getContent() {
        while (!ready){
            try {
                wait();
            }catch (InterruptedException e){

            }
        }
        return realData.getContent();
    }

    @Override
    public String toString() {
        return "feature.toString";
    }
}
public class Host {
    public Data request(final int count, final char c){
        System.out.println("    request("+count+" , "+c+") begin");
        //1,创建FutureData实例
        final FutureData futureData = new FutureData();
        //2,启动一个新线程去创建RealData实例,耗时操作
        new Thread(){
            @Override
            public void run() {
                RealData realData = new RealData(count,c);
                futureData.setRealData(realData);
            }
        }.start();
        System.out.println("    request("+count+" , "+c+") end");

        //3,将Future实例作为返回值返回给调用者
        return futureData;
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println(" main begin ..........");
        Host host = new Host();
        Data data1 = host.request(10,'a');
        System.out.println("虚拟数据:data1 = "+data1.toString());
        Data data2 = host.request(20,'b');
        System.out.println("虚拟数据:data2 = "+data2.toString());
        Data data3 = host.request(30,'c');
        System.out.println("虚拟数据:data3 = "+data3.toString());

        System.out.println(" main OtherJobs begin");
        try {
            //模拟主线程处理其他业务
            Thread.sleep(2000);
        }catch (InterruptedException e){

        }
        System.out.println(" main OtherJobs end");

        System.out.println("真实数据:data1 = "+data1.getContent());
        System.out.println("真实数据:data2 = "+data2.getContent());
        System.out.println("真实数据:data3 = "+data3.getContent());

        System.out.println(" main end ..........");
    }
}

三,特点

1,提高吞吐量
首先这种模式可以提高程序响应性,但是耗时的操作花费的时间并没有减少啊,当程序在进行磁盘读写时,cpu处于等待状态,这时可以把cpu分配给其他的线程,就可以提高吞吐量了

四,Callable和Future

public class CallableAndFuture {
    public static void main(String[] args) {

        ExecutorService threadPool= Executors.newSingleThreadExecutor();
        /*
        threadPool.submit()  返回有结果的
         */

        Future<String> future=      //Future是用来接收submit的结果的。泛型和Callable的结果一样
        threadPool.submit(new Callable<String>() {//这里泛型了,

            @Override
            public String call() throws Exception {
                Thread.sleep(1000);
                System.out.println("处理结果中。。。。");
                Thread.sleep(1000);
                return "hello";
            }
        });
        System.out.println("等待结果");
        try {
            System.out.println("拿到结果"+future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}
/**
 * 
 * CompletionService用于提交一组Callable任务,其task方法返回已完成的一个Callable任务对应的Future对象
 */
public class CallableAndFuture2 {
    public static void main(String[] args) {
        ExecutorService threadPool2= Executors.newFixedThreadPool(10);
        CompletionService<Integer> completionService = new ExecutorCompletionService(threadPool2);
        for (int i = 0; i < 10; i++) {
            final int seq = i;
            completionService.submit(new Callable() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(new Random().nextInt(5000));
                    return seq;
                }
            });
        }
        while (true){
            try {
                System.out.println(completionService.take().get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}
原文地址:https://www.cnblogs.com/inspred/p/9434558.html