java多线程模式之 Future模式

 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,等到其他线程终止处理后,再将结果setfuture,这样Client可以使用Future角色获取处理结果,这样可以在不要降低响应性的前提下获取处理结果。这就是Future模式。

猜你喜欢

转载自blog.csdn.net/qq_31350373/article/details/80486786