/**
* Future模式
* 模拟一个在没有锅和食材的情况下要进行烹饪的过程
*
* 1、Future代表:一个异步调用的未来的凭证,在做完其它事情之后 相当于JDK中的Future接口
* 再往下必须要返回结果时可以拿着这个凭证去进行get我们想要的返回结果
* 2、FutureTask代表:将调用逻辑和返回结果进行隔离 相当于JDK中的Callable接口
* 3、FutureService:是桥接Future和FutureTask的作用, 相当于JDK中的线程池服务(ExecutorService)
* 使Future不用知道FutureTask的具体逻辑,而FutureTask也不用知道有Future这个东西
*
* 调用者(client)只需要通过FutureService就可以完成自己的逻辑,不用关心其它
*
* @author xzq
*/
public class CallableAndFutureTest01 {
public static void main(String[] args) throws InterruptedException {
// String panResult = buyPan();
// String foodResult = buyFood();
// //使用同步的方式整个过程需要花费13秒的时间
// System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panResult+"里开始烹饪……");
FutureService<String> futureService=new FutureService<>();
Future<String> panFuture = futureService.submit(new FutureTask<String>(){
@Override
public String call() {
try {
return buyPan();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
});
String foodResult = buyFood();
//使用异步的方式整个过程需要花费10秒的时间
//……
System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panFuture.get()+"里开始烹饪……");
}
/**
* 在苏宁易购上,网购一个锅
* @throws InterruptedException
*/
private static String buyPan() throws InterruptedException {
System.out.println("打电话订购锅!");
System.out.println("快递正在将锅运往我家的途中……");
//需要花费10秒时间才能送到我家
Thread.sleep(10_000);
System.out.println("快递将锅送到我家,我已经收到并签收!");
return "锅";
}
/**
* 购买食材
* @throws InterruptedException
*/
private static String buyFood() throws InterruptedException {
System.out.println("出门去菜市场购买食材……");
//需要花费3秒时间才能买完食材回到家
Thread.sleep(3_000);
System.out.println("购买食材完毕回到家!");
return "食材";
}
/**
* 一个表示未来的事物的一个抽象
* @author Peter
*/
static interface Future<T>{
/**
* 获取结果方法
* @return
* @throws InterruptedException
*/
T get() throws InterruptedException;
}
/**
* 执行逻辑的抽象
* @author Peter
* @param <T>
*/
static interface FutureTask<T>{
/**
* 逻辑执行方法
* @return
*/
T call();
}
/**
* 桥接类
* @author Peter
* @param <T>
*/
static class FutureService<T>{
public Future<T> submit(final FutureTask<T> task){
final AsynFuture<T> asynFuture=new AsynFuture<>();
new Thread(){
//这里相当于购买锅后快递将锅送到家的过程
@Override
public void run() {
T result = task.call();
//得到结果后通知asynFuture已经完成了
asynFuture.done(result);
}
}.start();
return asynFuture;
}
}
/**
* 异步Future实现类
* @author Peter
* @param <T>
*/
static class AsynFuture<T> implements Future<T>{
private volatile boolean isDone=false;
private T result;
public void done(T result){
synchronized (this) {
this.result=result;
this.isDone=true;
this.notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this) {
while(!isDone){
//没有完成就等待
this.wait();
}
}
//完成了就把结果返回
return result;
}
}
}
2、加入回调模式更加优化Future模式
/**
* 加入回调模式更加优化Future模式
* 前面阻塞的方式就是等于轮询的方式,这里采用回调方式是一种非阻塞方式
* @author xzq
*/
public class CallableAndFutureTest02 {
private static String panResult=null;
public static void main(String[] args) throws InterruptedException {
FutureService<String> futureService=new FutureService<>();
//这里就不需要一个未来用于获取结果的凭证了
futureService.submit(new FutureTask<String>(){
@Override
public String call() {
try {
return buyPan();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
},
//这里是送到家门口的快递取货箱默认我已签收
new NoResultCallBack<String>() {
@Override
public void backResult(String result) {
panResult=result;
}
});
String foodResult = buyFood();
//使用异步的方式整个过程需要花费10秒的时间
if(panResult==null){
//可以干别的事情
}else{
System.out.println("开始烹饪!!!,把"+foodResult+"放进"+panResult+"里开始烹饪……");
}
}
/**
* 在苏宁易购上,网购一个锅
* @throws InterruptedException
*/
private static String buyPan() throws InterruptedException {
System.out.println("打电话订购锅!");
System.out.println("快递正在将锅运往我家的途中……");
//需要花费10秒时间才能送到我家
Thread.sleep(10_000);
System.out.println("快递将锅送到我家,我已经收到并签收!");
return "锅";
}
/**
* 购买食材
* @throws InterruptedException
*/
private static String buyFood() throws InterruptedException {
System.out.println("出门去菜市场购买食材……");
//需要花费3秒时间才能买完食材回到家
Thread.sleep(3_000);
System.out.println("购买食材完毕回到家!");
return "食材";
}
/**
* 一个表示未来的事物的一个抽象
* @author Peter
*/
static interface Future<T>{
/**
* 获取结果方法
* @return
* @throws InterruptedException
*/
T get() throws InterruptedException;
}
/**
* 执行逻辑的抽象
* @author Peter
* @param <T>
*/
static interface FutureTask<T>{
/**
* 逻辑执行方法
* @return
*/
T call();
}
/**
* 桥接类
* @author Peter
* @param <T>
*/
static class FutureService<T>{
public Future<T> submit(final FutureTask<T> task,final NoResultCallBack<T> callBack){
final AsynFuture<T> asynFuture=new AsynFuture<>();
new Thread(){
//这里相当于购买锅后快递将锅送到家的过程
@Override
public void run() {
T result = task.call();
//得到结果后通知asynFuture已经完成了
asynFuture.done(result);
//并且将结果返回给调用方
callBack.backResult(result);
}
}.start();
return asynFuture;
}
}
/**
* 回调接口
* @author Peter
* @param <V>
*/
static interface NoResultCallBack<V>{
void backResult(V result);
}
/**
* 异步Future实现类
* @author Peter
* @param <T>
*/
static class AsynFuture<T> implements Future<T>{
private volatile boolean isDone=false;
private T result;
public void done(T result){
synchronized (this) {
this.result=result;
this.isDone=true;
this.notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this) {
while(!isDone){
//没有完成就等待
this.wait();
}
}
//完成了就把结果返回
return result;
}
}
}