1. 模式定义
Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。
当我们需要调用一个函数方法时,如果这个函数执行很慢,那么我们就要进行等待。
但有时候,我们可能并不急着要结果。
因此,我们可以让被调者立即返回,让它在后台慢慢处理这个请求。
对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获得需要的数据Future模式有点类似在网上买东西。
如果我们在网上下单买了一个手机,当我们支付完成后,手机并没有办法立即送到家里,但是在电脑上会立即产生一个订单。
这个订单就是将来发货或者领取手机的重要凭证,这个凭证也就是 Future模式中会给出的一个契约。
在支付活动结束后,大家不会傻傻地等着手机到来,而是可以各忙各的。
而这张订单就成为了商家配货、发货的驱动力。当然,这一切你并不用关心。
你要做的,只是在快递上门时,开一下门,拿一下货而已。
对于 Future模式来说,虽然它无法立即给出你需要的数据。但是,它会返回给你一个契约将来,你可以凭借着这个契约去重新获取你需要的信息。
2. 模式流程
传统串行模式
![](https://i-blog.csdnimg.cn/blog_migrate/1ee39ebba0e668bc55810f9b42410e23.png)
如图5.6所示,显示了通过传统的同步方法,调用一段比较耗时的程序。
客户端发出Call请求,这个请求需要相当长一段时间才能返回。
客户端一直等待,直到数据返回,随后,再进行其他任务的处理。
3. 角色定义
4. 程序代码
package com.john.learn.high.concurent.ch04.future;
public interface Callable<T> {
public T execute();
}
package com.john.learn.high.concurent.ch04.future;
ublic interface Future<T> {
public T get() throws InterruptedException;
}
package com.john.learn.high.concurent.ch04.future;
public class FutureCertificate<T> implements Future<T> {
private boolean ready;
private T result;
@Override
public synchronized T get() throws InterruptedException {
while (!ready) {
wait();
}
return result;
}
public void set(T result) {
if (this.ready) {
return;
}
this.result = result;
this.ready = true;
synchronized (this) {
this.notifyAll();
}
}
}
package com.john.learn.high.concurent.ch04.future;
import java.util.concurrent.ExecutorService;
public class FutureClient {
public <T> Future<T> execute(final Callable<T> callable) {
final FutureCertificate<T> futureCertificate = new FutureCertificate<>();
// 线程中处理
Thread processor = new Thread() {
public void run() {
// 处理完毕,Notify Get wait
futureCertificate.set(callable.execute());
}
};
processor.start();
// 立即返回
return futureCertificate;
}
public FutureClient() {
}
}
package com.john.learn.high.concurent.ch04.future;
public class FutureMain {
public static void main(String[] args) throws InterruptedException {
Callable<Long> callable = new Callable<Long>() {
@Override
public Long execute() {
System.out.println("Start to process");
//模拟耗时
try {
Thread.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed process");
return System.currentTimeMillis();
}
};
FutureClient futureClient =new FutureClient();
System.out.println( futureClient.execute(callable).get());
}
}