一、Future模式概述
二、Future序列图
三、示例代码
一、Future模式概述
Future类似于商品订单问题,当用户看上一件商品之后,下单完成在家里等待送货上门即可。更形象的一个例子就是页面发送AJAX请求,页面异步进行后台处理,用户无需一直等待结果,可以浏览其他东西。
Future的原理是:当你申请资源(计算资源或I/O资源)时,立即返回一个虚拟的资源句柄,当真正使用的时候,再将虚拟的句柄转化成真正的资源,相当于预获取。
二、Future序列图
三、代码示例
(1)FutureData类与RealData类共同实现同一个接口
package net.oschina.tkj.mulitcoding.futuremodel;
/**
* 数据接口,用户请求数据,并且返回用户需要真实数据
*
* @author Freedom
*
*/
public interface Data {
String getRequest(String req);
}
(2)FutureData类(类似一个空的包装类)
该类只有获取到真实数据之后,当用户需要数据时,才能继续执行。
package net.oschina.tkj.mulitcoding.futuremodel;
/**
* FutureData数据包装类,用户直接与该类进行交互
*
* 用户将请求发送到该类,由该类异步的获取真实的数据
*
* @author Freedom
*
*/
public class FutureData implements Data {
private RealData realData = null;
private static final Object lock = new Object();
private boolean isReady = false;
/**
* 处理client请求的方法
*
* 用户需要数据时,调用该方法拿到真实数据
*/
@Override
public String getRequest(String req) {
synchronized (lock) {
if (!isReady) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return realData.getRequest(req);
}
}
/**
* 用于设置包装类中的数据
*
* @param data
*/
public void setRealData(RealData data) {
synchronized (lock) {
if (isReady) {
return;
}
this.realData = data;
isReady = true; // 有真实数据表示
// 唤醒获取数据的线程
lock.notify();
}
}
}
(3)真实数据类
package net.oschina.tkj.mulitcoding.futuremodel;
import java.util.concurrent.TimeUnit;
/**
* 真实数据的类,与FutureData类进行交互,该类提供真实数据
*
* @author Freedom
*
*/
public class RealData implements Data {
private String data;
/**
* 设置真实数据
*/
public synchronized void setRealData() {
System.out.println("获取真实数据开始...此过程很耗时...");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("获取到了真实数据...");
data = "这是这真实数据";
}
@Override
public String getRequest(String req) {
return data;
}
}
(4)客户端类
package net.oschina.tkj.mulitcoding.futuremodel;
/**
* Future模式的客户端
*
* 用于获取到数据包装类对象
*
* @author Freedom
*
*/
public class FutureCli {
public synchronized Data getFutureData(String req) {
final FutureData data = new FutureData();
/*
* 模块核心部分,开启一个线程,目的为了异步获取真实数据
*/
new Thread(new Runnable() {
@Override
public void run() {
RealData real = new RealData();
real.setRealData();
// 将获取到的真实数据设置到包装类中
data.setRealData(real);
}
}).start();
return data;
}
}
(5)主类
package net.oschina.tkj.mulitcoding.futuremodel;
public class Main {
public static void main(String[] args) {
FutureCli cli = new FutureCli();
Data data = cli.getFutureData("用户发来的请求参数信息...");
System.out.println("获取数据的过程ing......");
// 获取到的真实数据
System.out.println(data.getRequest("请求参数...."));
}
}