Future模式
假如有一个方法需要花费很长时间才能获取运行结果,那么,与其一直等待结果,不如先拿一张“提货单”。
实例类图:
Host类:
创建FutureData的实例
启动一个新线程(相当于制作蛋糕的蛋糕店),用于创建RealData的实例
将FutureData的实例作为返回值返回给调用者
其中future.setRealData(realdata);
相当于在顾客拿着提货单来取货之前制作蛋糕的过程。
public class Host {
public Data request(final int count,final char c){
System.out.println("request("+count+","+c+")begin");
//1创建FutrueData 的实例
final FutrueData future = new FutrueData();
//2启动一个新线程,用于创建RealData的实例
new Thread(){
public void run(){
RealData realdata = new RealData(count, c);
future.setRealData(realdata);
}
}.start();
System.out.println("request("+count+","+c+")end" );
return future;
}
}
Data接口
public interface Data {
public abstract String getContent();
}
FutureData类:
表示提货单的类
realData 用于保存稍后创建完的RealData实例
ready表示是否已经为realData赋值的字段(true表示已赋值,蛋糕制作完成)
setRealData用于将RealData实例赋值给realData字段的方法,如果RealData创建完成,将ready设置true,notifyAll唤醒getContent(),getContent()方法未唤醒前无法取走蛋糕。
这里的getContent()委托给了RealData类的getContent()
public class FutrueData implements Data{
private RealData realdata = null;
private boolean ready =false;
public synchronized void setRealData(RealData realdata){
if(ready){
return ;
}
this.realdata = realdata;
this.ready =true;
notifyAll();
}
@Override
public synchronized String getContent() throws ExecutionException {
while(!ready){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return realdata.getContent();
}
}
RealData类,需要花费长时间需要创建的实例的类(相当于蛋糕)
public class RealData implements Data {
private final String content;
public RealData(int count,char c){
System.out.println(" making RealData("+count+","+c+")begin");
char[] buffer = new char[count];
for(int i =0;i<count;i++){
buffer[i] = c;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(" making RealData("+count+","+c+")end");
this.content = new String(buffer);
}
@Override
public synchronized String getContent() {
// TODO Auto-generated method stub
return content;
}
}
Main类
测试执行类
public class Main {
public static void main(String[] args) {
System.out.println("main begin");
Host host = new Host();
Data data1 = host.request(10, 'A');
Data data2 = host.request(20, 'B');
Data data3 = host.request(30, 'C');
System.out.println(" main otherJob begin");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(" main otherJob end");
System.out.println("data1 = "+data1.getContent());
System.out.println("data2 = "+data2.getContent());
System.out.println("data3 = "+data3.getContent());
System.out.println("main END");
}
}
执行结果:
main begin
request(10,A)begin
request(10,A)end
request(20,B)begin
request(20,B)end
request(30,C)begin
request(30,C)end
main otherJob begin
making RealData(10,A)begin
making RealData(30,C)begin
making RealData(20,B)begin
main otherJob end
making RealData(10,A)end
data1 = AAAAAAAAAA
making RealData(20,B)end
data2 = BBBBBBBBBBBBBBBBBBBB
making RealData(30,C)end
data3 = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
main END
总结:
Thread-Per-Message模式将消耗时间的处理交给其他线程,的确可以提高程序的响应性,但是在将处理转交出去的时候,处理结果依然不知,这样程序的响应性又会降低,使用Futrue模式,
首先编写一个表示处理结果的RealData和具有相同接口的Future,接着处理开始时先返回Future,等到其他线程终止处理后,再将结果set到future,这样Client可以使用Future角色获取处理结果,这样可以在不要降低响应性的前提下获取处理结果。这就是Future模式。