并发设计模式 Future模式

核心思想

异步调用。先拿到一个Future,然后根据Future拿真实数据。

示例1

public interface Data {
    String getResult();
}
/**
 * 这是关键类,包装了RealData,代替RealData先返回。
 * 通过该类获取RealData,如果RealData结果出来则直接返回,如果还没有则阻塞等待。
 */
public class FutureData implements Data {

    /**包装RealData*/
    protected RealData realData = null;
    protected boolean isReady = false;

    public synchronized void setRealData(RealData realData) {
        if (isReady) {
            return;
        }
        this.realData = realData;
        this.isReady = true;
        // RealData已经被注入,通知getResult()
        notifyAll();
    }

    @Override
    public synchronized String getResult() {
        // 等待RealData构造完成
        while (!isReady) {
            try {
                // 一直等待,RealData被注入
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return realData.getResult();
    }
}
public class RealData implements Data {

    protected final String result;

    public RealData(String result) {
        // RealData的构造可能很慢,需要等待很久,这里使用Sleep模拟。
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.result = result;
    }


    @Override
    public String getResult() {
        return result;
    }
}
public class Client {

    public Data request(String queryStr) {
        FutureData futureData = new FutureData();
        //RealData构建很慢,单开线程。
        new Thread(()->{
            RealData realData = new RealData(queryStr);
            futureData.setRealData(realData);
        }).start();
        //FutureData立即返回
        return futureData;
    }

}
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Client client = new Client();
        //立即返回得到的是FutureData,稍后通过这个FutureData的getResult获取RealData
        Data data = client.request("baozi-request");

        //这里模拟其他业务的处理,在这个过程中RealData慢慢构建成功
        Thread.sleep(2000);

        System.out.println("获取RealData:"+data.getResult());
    }
}

示例2 JDK内置

FutureTask代替Callable先返回,稍后通过FutureTask获取Callable获取的数据。

import java.util.concurrent.Callable;

public class RealData implements Callable<String> {

    @Override
    public String call() throws Exception {
        //RealData的构造可能很慢,需要等待很久,这里使用Sleep模拟。
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "callable";
    }
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Test {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        FutureTask<String> futureTask = new FutureTask<String>(new RealData());
        ExecutorService es = Executors.newFixedThreadPool(1);
        // FutureTask执行Callable,开启线程进行RealData的call执行
        es.submit(futureTask);

        // 这里模拟其他业务的处理,在这个过程中RealData慢慢构建成功
        Thread.sleep(2000);

        // 再次说明,先构建FutureTask,然后通过FutureTask执行Callable获取返回值
        // 1.如果Callable没有返回则等待,2.已返回则返回
        System.out.println("call:"+futureTask.get());
        es.shutdown();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容