一、什么是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高并发程序设计》