Promise模式
一种异步编程的模式,使得我们可以先开始一个任务的执行,并得到一个用于获取该任务执行结果的凭据对象,不用去等该任务执行完成可以执行其他操作,在生活中我们也经常会运用其中的思想,比如我们去一家小吃店点了一份鸭血粉丝和一份小笼包,会发一份凭据,鸭血粉丝比较快做好,我们可以不用等待小笼包做好,先吃鸭血粉丝,等到吃的差不多了,小笼包也可能出笼了,我们可以凭着发票换取小笼包。
吃早餐的两两种执行方式
同步等待的方式:
异步的方式:
//同步的方式执行我们知道是最耗时的
//异步的方式,也存在一个问题,我们先看代码
public class Test {
public static void main(String[] args) throws Exception{
long starTime = System.currentTimeMillis();
Thread thread = new Thread(()->{
System.out.println("开始吃鸭血粉丝");
try {
Thread.sleep(5*1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("吃完鸭血粉丝");
});
thread.start();
System.out.println("等到小笼包");
System.out.println("开始吃小笼包");
Thread.sleep(3*1000);
System.out.println("吃完小笼包");
long endTime = System.currentTimeMillis();
System.out.println("一共耗时:"+(endTime-starTime)+"ms");
}
}
从结果上我们可以看到,主线程已经结束了,但是任务1(鸭血粉丝还没有吃完)还没有执行完。此时就需要用到我们的Promise模式。
Promise模式介绍
Promise模式主要是由4个部分构成:
- Promisor 负责对外暴露可以返回Promise对象的异步方法compute(),并启动异步执行任务
Compute方法:启动异步任务的执行,返回promise对象 - TaskExecutor 负责真正执行的异步任务,在Promisor定义的任务,由TaskExecutor来执行
- Promise Promisor的compute方法返回的凭据对象,主要负责检查异步任务是否完成,返回异步任务的处理结果
get 获取异步任务的执行结果
isDone 检测异步任务是否执行完毕 - Result
异步任务的处理结果
代码实现过程:
public class Baozi {
boolean status = false;
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
public class Promisor {
public static Future<Object> compute(){
FutureTask<Object> futureTask = new FutureTask<>(()->{
System.out.println("开始做小笼包");
Baozi baozi = new Baozi();
Thread.sleep(2*1000);
baozi.setStatus(true);
return baozi;
});
new Thread(futureTask).start();
return futureTask;
}
}
public class Test {
public static void main(String[] args) throws Exception{
long startTime = System.currentTimeMillis();
Future<Object> promisor = Promisor.compute();
System.out.println("开始吃鸭血粉丝");
Thread.sleep(7*1000);
System.out.println("鸭血粉丝吃完");
if(!promisor.isDone()){
System.out.println("等待小笼包做好");
}
Baozi baozi = (Baozi)promisor.get();
System.out.println("得到包子做完信号");
System.out.println("开始吃包子");
System.out.println("一共耗时:"+(System.currentTimeMillis()-startTime)+"ms");
}
}