一,Future模式
假设有一个方法需要花费很长的时间才能获取运行结果。那么,与其一直等待结果,不如先拿一张 提货单。获取提货单并不耗费时间。这里提货单就称为Future角色
获取Future角色的线程会在稍后使用Future角色来获取运行结果
在处理开始时先返回Future角色,等到其他线程出来终止后,在将结果设置到Future角色中。
二,示例程序
Data:访问数据的接口
RealData:实际处理数据的类
FutureData:表示RealData的提货单,
Host:先拿提货单future实例,开启新线程创建RealData实例
public interfaceData {public abstractString getContent();
}
public class RealData implementsData {private finalString content;public RealData(int count,charc){
System.out.println(" making RealData("+count+" , "+ c +") begin");char[] buffer = new char[count];for (int i = 0; i
buffer[i]=c ;try{
Thread.sleep(100);
}catch(InterruptedException e){
}
}
System.out.println(" making RealData("+count+" , "+ c +") end");this.content = newString(buffer);
}
@OverridepublicString getContent() {returncontent;
}
@OverridepublicString toString() {return "real.toString";
}
}
public class FutureData implementsData {private RealData realData = null;private boolean ready = false;/*** 为Future类中的字段设置值
*@paramrealData*/
public synchronized voidsetRealData(RealData realData) {if(ready){return;
}this.realData =realData;this.ready = true;
notifyAll();
}/*** 还没有成功设置值之前 一直等待。设置成功后就返回值
*@return
*/@Overridepublic synchronizedString getContent() {while (!ready){try{
wait();
}catch(InterruptedException e){
}
}returnrealData.getContent();
}
@OverridepublicString toString() {return "feature.toString";
}
}
public classHost {public Data request(final int count, final charc){
System.out.println(" request("+count+" , "+c+") begin");//1,创建FutureData实例
final FutureData futureData = newFutureData();//2,启动一个新线程去创建RealData实例,耗时操作
newThread(){
@Overridepublic voidrun() {
RealData realData= newRealData(count,c);
futureData.setRealData(realData);
}
}.start();
System.out.println(" request("+count+" , "+c+") end");//3,将Future实例作为返回值返回给调用者
returnfutureData;
}
}
public classTest {public static voidmain(String[] args) {
System.out.println(" main begin ..........");
Host host= newHost();
Data data1= host.request(10,'a');
System.out.println("虚拟数据:data1 = "+data1.toString());
Data data2= host.request(20,'b');
System.out.println("虚拟数据:data2 = "+data2.toString());
Data data3= host.request(30,'c');
System.out.println("虚拟数据:data3 = "+data3.toString());
System.out.println(" main OtherJobs begin");try{//模拟主线程处理其他业务
Thread.sleep(2000);
}catch(InterruptedException e){
}
System.out.println(" main OtherJobs end");
System.out.println("真实数据:data1 = "+data1.getContent());
System.out.println("真实数据:data2 = "+data2.getContent());
System.out.println("真实数据:data3 = "+data3.getContent());
System.out.println(" main end ..........");
}
}
三,特点
1,提高吞吐量
首先这种模式可以提高程序响应性,但是耗时的操作花费的时间并没有减少啊,当程序在进行磁盘读写时,cpu处于等待状态,这时可以把cpu分配给其他的线程,就可以提高吞吐量了
四,Callable和Future
public classCallableAndFuture {public static voidmain(String[] args) {
ExecutorService threadPool=Executors.newSingleThreadExecutor();/*threadPool.submit() 返回有结果的*/Future future= //Future是用来接收submit的结果的。泛型和Callable的结果一样
threadPool.submit(new Callable() {//这里泛型了,
@Overridepublic String call() throwsException {
Thread.sleep(1000);
System.out.println("处理结果中。。。。");
Thread.sleep(1000);return "hello";
}
});
System.out.println("等待结果");try{
System.out.println("拿到结果"+future.get());
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
}
/***
* CompletionService用于提交一组Callable任务,其task方法返回已完成的一个Callable任务对应的Future对象*/
public classCallableAndFuture2 {public static voidmain(String[] args) {
ExecutorService threadPool2= Executors.newFixedThreadPool(10);
CompletionService completionService = newExecutorCompletionService(threadPool2);for (int i = 0; i < 10; i++) {final int seq =i;
completionService.submit(newCallable() {
@Overridepublic Integer call() throwsException {
Thread.sleep(new Random().nextInt(5000));returnseq;
}
});
}while (true){try{
System.out.println(completionService.take().get());
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
}
}