Java并发编程 | 第四篇:Future模式

释放双眼,带上耳机,听听看~!

一、什么是Future模型

常见的多线程设计模式有:单例模式、不变模式、生产者-消费者模式、Future模式;而这里介绍Future模式,它的核心思想就是
异步调用。当我们需要调用一个函数,但是这个函数执行很慢,如果我们不需要马上知道结果,
我们可以立即返回,让它在后台慢慢处理这个请求,对于调用者来说,可以先处理一些其他任务,这个就充分利用等待时间

在真正需要数据场合再去尝试获取需要的数据。


二、Future模式的主要角色

主要参与者如表:

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

核心结构


三、Future模式的简单实现

实现中有一个核心接口就是Data,这是客户端希望获取的数据,这个Data接口有两个重要的实现,分别是RealData,也就是真实数据,这就是我们最终需要获取的信息,还有一个FutureData,它用来提取RealData的一个“订单”因此FutureData可以立即获得

Data接口


1
2
3
4
1public interface Data {
2     public String getResult();
3}
4

实现类FutureData

这个是Future模式的关键,
实际上是真实数据RealData的代理,封装了获取RealData的等待过程


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1public class FutureData implements Data{
2
3    protected RealData realdata=null;//FutureData是RealData的包装
4    protected boolean isReady=false;
5
6    public synchronized void setRealData(RealData realdata){
7        if(isReady){
8            return;
9        }
10        this.realdata=realdata;
11        isReady=true;
12        notifyAll();//RealData已经被注入,通知getResult()
13    }
14
15    @Override
16    public  synchronized String getResult() {  //会等待RealData构造完成
17        // TODO Auto-generated method stub
18        while(!isReady){
19            try {
20                wait();     //一直等待,知道RealData被注入
21            } catch (Exception e) {
22                // TODO: handle exception
23            }
24        }
25
26        return realdata.result;
27    }
28
29}
30

FutureData实现了一个快速返回的RealData包装,所以它只是一个包装,没有真实数据,在里面的getResult()方法如果实际数据没有准备好就等待,直到RealData准备好并注入FutureData才返回数据

实现类RealData


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1public class RealData implements Data {
2
3    protected final String result;// protected可访问同包的元素
4
5    public RealData(String para) {
6        // RealData的构造可能很慢,需要用户等待好久,这里使用sleep模拟
7        StringBuffer sb = new StringBuffer();
8        for (int i = 0; i < 10; i++) {
9            sb.append(para);
10
11            try {
12                Thread.sleep(100);
13            } catch (Exception e) {
14                // TODO: handle exception
15            }
16        }
17
18        result = sb.toString();
19    }
20
21    @Override
22    public String getResult() {
23        // TODO Auto-generated method stub
24
25        return result;
26    }
27
28}
29

Client

在客户端程序,创建获取FutureData,并开启构造RealData的线程,立即返回FutureData


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1public class Client {
2      public Data request(final String queryStr){
3          final FutureData future=new FutureData();//实现获取FutureData
4          new Thread(){        
5              public void run(){    //RealData的构造很慢,所以在单独的线程中进行
6                  RealData realdata=new RealData(queryStr);
7                  future.setRealData(realdata);
8              }
9          }.start();
10          return future;//FutureData会被立即返回
11      }
12
13}
14

主函数

负责调用Client发起请求 ,并消费返回的数据


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2      public static void main(String[] args) {
3        Client client=new Client();
4        //这里会立即返回,因为得到FutureData,而不是RealData
5        Data data=client.request("name");
6        System.out.println("请求完毕");
7        try {
8            //这里可以用一个sleep代替对其他业务逻辑的处理
9            //在处理这些业务逻辑中,RealData被创建,从而充分利用了等待时间
10            Thread.sleep(2000);
11        } catch (Exception e) {
12            // TODO: handle exception
13        }
14        System.out.println("数据="+data.getResult());
15    }
16

参考:《Java高并发程序设计》

给TA打赏
共{{data.count}}人
人已打赏
安全技术

网站制作需要素材的实用网站

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索