Future模式类似于js中的ajax等,是一个异步获取数据的机制,这里我把自己的一些形象理解通过代码实现了一下。
该机制可以形象的理解为:调用获取数据的方法,首先获得一个没有装数据的空箱子(这个箱子有获取数据和装载数据的机制),至于箱子中的数据是通过另开一个线程去获取的,隔一段时间之后,当我们想要获取箱子中的数据的时候,就直接从箱子中拿就行了,一般情况下,由于获取到箱子之后到我需要从箱子中拿取数据应该已经过了一段时间(因为做其他一些操作),正是这一段时间,数据通过其它线程已经被存放到箱子中了。
/**
* 测试
* @author yangcheng
*
*/
public class MainTest {
public static void main(String[] args){
Client client=new Client();
//拿到空箱子箱子
FeatureCar result=(FeatureCar) client.requestData("这是我发送的数据");
System.out.println("继续执行其他业务");
//从空箱子中获取数据 如果数据没有则等待,一直等到拿到数据位置————因此 在获取箱子中的数据之前可以做一些其它操作
System.out.println(result.getResult());
}
}
/**
* 客户端中,使用近似于javascript中的ajax的异步请求数据的这种方式获取数据
*
* 该客户端作用 需要构建异步数据获取的结构,以便让main方法直接使用该类对象获取其数据
*
* @author yangcheng
*
*/
public class Client {
//
public Data requestData(final String msg){
//创建一个同步对象直接返回(盛放物品的箱子)
final FeatureCar car=new FeatureCar();
//创建一个线程 用于获取数据(获取箱子中的物品,这个物品是在把箱子已经交给请求者之后,慢慢放进箱子中的)
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
FeatureRealData realData=new FeatureRealData(msg);
//把真实的数据放到箱子里面
car.setRealData(realData);
}
}).start();;
//把箱子先返回给调用者 而里面的数据是通过上面的线程异步放进去的
return car;
}
}
/**
* 箱子
* 用于同步返回客户端请求的数据(装东西的“箱子”,刚刚返回给调用者时箱子是空的,里面的数据是通过异步线程获取的)
*
* @author yangcheng
*
*/
public class FeatureCar implements Data{
//组合一个真实数据对象
private FeatureRealData realData;
//这里需要设置一个标识用于判断realData对象中是否为null,如果为null的时候getResult方法被执行,就需要把getResult阻塞(wait())
//默认没有值
private boolean flag=false;
public synchronized void setRealData(FeatureRealData realData) {
if(flag){
try {
//如果在非synchronized方法中调用方法 wait notify notifyAll 会报"java.lang.IllegalMonitorStateException"
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//默认setRealData方法可以直接执行 不会阻塞,
flag=true;
notify();
this.realData = realData;
}
@Override
public synchronized String getResult() {
// TODO Auto-generated method stub
while(true){
if (!flag) {
try {
//当realData对象为null 线程等待
System.err.println("**************************");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
return realData.getResult();
}
}
}
/**
* 被装到箱子里面的“物品”
*
* 该类的作用就是 访问数据库 并将结果返回
* @author yangcheng
*
*/
public class FeatureRealData implements Data{
private String resultData;
//模拟访问数据库
public FeatureRealData(String msg){
try {
//模拟数据库访问花了3秒
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resultData= "返回的真实数据:数据获取成功!";
}
//将查询结果返回
@Override
public String getResult() {
// TODO Auto-generated method stub
return resultData;
}
}
/**
* 该接口用于规范获取数据的方法
* @author yangcheng
*
*/
public interface Data {
public String getResult();
}