java promise(GitHub)是Promise A+规范的java实现版本。Promise A+是commonJs规范提出的一种异步编程解决方案,比传统的解决方案—回调函数和事件—更合理和更强大。promise实现了Promise A+规范,包装了java中对多线程的操做,提供统一的接口,使得控制异步操做更加容易。实现过程当中参考文档以下:java
基本使用:git
<repositories>
<repository>
<id>wjj-maven-repo</id>
<url>https://raw.github.com/zhanyingf15/maven-repo/master</url>
</repository>
</repositories>
复制代码
<dependency>
<groupId>com.wjj</groupId>
<artifactId>promise</artifactId>
<version>1.0.0</version>
</dependency>
复制代码
IPromise promise = new Promise.Builder().promiseHanler(new PromiseHandler() {
@Override
public Object run(PromiseExecutor executor) throws Exception {
return 2*3;
}
}).build();
复制代码
上面的例子中建立了一个promise对象,指定PromiseHandler实现,在run方法中写具体的业务逻辑,相似于Runable的run方法。promise对象一经建立,将当即异步执行。推荐使用lambda表达式,更加简洁。es6
IPromise promise = new Promise.Builder().promiseHanler(executor -> {
return 2*3;
}).build();
复制代码
获取promise的执行结果一般使用两个方法then
和listen
,前者是阻塞的后者是非阻塞的。then方法返回一个新的promise对象,所以支持链式调用。github
new Promise.Builder().promiseHanler(executor -> {//promise0
return 2*3;
}).build().then(resolvedData -> {//返回一个新的promise1
System.out.println(resolvedData);
return (Integer)resolvedData+1;
}).then(res2->{
System.out.println(res2);
//建立一个新的promise2并返回
return new Promise.Builder().externalInput(res2).promiseHanler(executor -> {
return (Integer)executor.getExternalInput()+2;
}).build();
}).then(res3->{
System.out.println(res3);
return res3;
});
复制代码
从上面能够看到promise0、promise1和Promise2是链式调用的,每一次then方法都返回一个新的promise。在then方法的回调中,若是返回的是一个非promise对象,那么promise被认为是一个fulfilled状态的promise,若是返回的是一个promsie实例,那么该实例将会异步执行。
假如须要异步顺序执行a->b-c->d四个线程,调用顺序以下编程
new PromiseA()
.then(dataA->new PromiseB())//A的回调
.then(dataB->new PromiseC())//B的回调
.then(dataC->new PromiseD())//C的回调
.then(dataD->xxx)//D的回调
.pCatch(error->xxxx)//捕获中间可能产生的异常
复制代码
具体使用 方式参考promise-java异步编程解决方案数组
promise规范能够参考 Promise A+规范。其中ES6 Promise对象 在Promise A+规范上作了一些补充。java promise在使用上基本与ES6 Promise对象保持一致,部分地方有些许不一样,后面会作出说明。 Promise的三个状态promise
Promise是IPromise的实现,Promise实例一经建立,将当即异步执行,部分接口以下bash
then(null,onRejectedExecutor)的别名,但返回不一样于then,出现异常时能够选择不拒绝接下来Promise的执行,可用于异常修正,相似于try{}catch{}
该方法会尝试捕获当前promise的异常,最终返回一个新Promise,当被捕获Promise处于不一样的状态时有不一样的行为多线程
指定一个监听器,在promise状态转为fulfilled或rejected调用,该方法不会阻塞线程执行,能够屡次调用指定多个监听器异步
listen的别名,行为同listen
获取promise的当前状态
获取promise fulfilled状态下的终值,其他状态下时为null
获取promise rejected状态下的拒因,其他状态下为null
获取promise对应异步任务的future
尝试取消promise对应的异步任务,底层调用future.cancel(true)。fulfilled或rejected状态下无效。
Promise对象生成器
指定一个线程池用于执行promise任务,若是不指定,每个promise都将启动一个线程
指定promise执行器,在promiseHanler的run方法中实现线程的具体业务逻辑,注意==promise对象一经建立,将当即执行其中的逻辑==
向Promise注入一个外部参数,能够在指定PromiseHandler时经过PromiseExecutor.getExternalInput()获取
int i = 3;
IPromise p = new Promise.Builder()
.externalInput(i).promiseHanler(new PromiseHandler() {
public Object run(PromiseExecutor executor) {
Integer args = (Integer) executor.getExternalInput();
return args*2;
}
}).build();
复制代码
指定一个promise x,使当前promise接受 x 的状态
ExecutorService fixedPool = Promise.pool(1);
IPromise promise1 = new Promise.Builder().pool(fixedPool).promiseHanler(executor->3).build();
IPromise promise2 = new Promise.Builder().pool(fixedPool)
.promise(promise1)
.promiseHanler(executor->4+(Integer) executor.getPromiseInput())
.build()
.then(resolvedData->{
System.out.println(resolvedData);
return resolvedData;
}, rejectedReason-> rejectedReason.printStackTrace());
复制代码
最终结果返回7,。若是promise1在执行过程当中抛出异常e,promise2将被拒绝执行,将会以e做为拒因,状态为rejected返回一个新的Promise,最终会执行rejectedReason-> rejectedReason.printStackTrace()
回调。
建立一个Promise实例
将多个 Promise 实例p1,...pn,包装成一个新的 Promise 实例 p,只有当p1-pn的状态都转为fulfilled时,p的状态才为fulfilled,此时p1-pn的返回值包装为一个数组Object[r1,...rn]做为p的终值。
只要p1-pn中任意一个被rejected,p的状态就转为rejected,将第一个被rejected的promise的拒因做为p的拒因,并尝试取消其他promise的执行(内部调用future.cancel(true))
将多个 Promise p1,...pn实例,包装成一个新的 Promise 实例 p,只要p1-pn有一个状态发生改变,p的状态当即改变。并尝试取消其他promise的执行(内部调用future.cancel(true))
第一个改变的promise的状态和数据做为p的状态和数据
建立一个终值为null、fulfilled状态的promise
建立一个终值为object、fulfilled状态的promise
将object的then方法以异步方式执行,then方法的执行结果做为Promise的终值
将object的指定方法以异步方式执行,该方法的执行结果做为Promise的终值,目标方法的参数必须按顺序包含在List中,如object.doSomething(int a,Map b),用resolve执行为
List args = new ArrayList()
args.add(1);
args.add(map)
Promise.resolve(object,"doSomething",args);
复制代码
建立一个拒由于reason、rejected状态的promise
将object的指定方法以同步方式执行,该方法的执行结果做为Promise的终值,若是object为IPromise实例,将忽略methodName和args参数,异步执行该实例。
该方法是以Promise统一处理同步和异步方法,无论object是同步操做仍是异步操做,均可以使用then指定下一步流程,用pCatch方法捕获异常,避免开发中出现如下状况
try{
object.doSomething(args1,args2);//可能会抛出异常
promise.then(resolvedData->{
//一些逻辑
}).then(resolvedData->{
//一些逻辑
}).pCatch(e->{
//异常处理逻辑
})
}catch(Exception e){
//异常处理逻辑
}
复制代码
使用pTry,能够简化异常处理
List args = new ArrayList(){args1,args2};
Promise.pTry(object,"doSomething",args)
.then(resolvedData->{
//一些逻辑
}).then(resolvedData->{
//一些逻辑
}).pCatch(e->{
//异常处理逻辑
})
复制代码
定义异步逻辑的接口
run方法中实现具体的业务逻辑,最终run方式是在线程的call方法执行,若是run方法中含有wait、sleep...等锁操做,可能须要自行处理InterruptedException
。由于该线程可能被外部调用cancel()或interrupt()方法
promise状态处理
将Promise对象的状态从“未完成”变为“成功”(即从pending变为fulfilled)。注意该方法一经调用,promise状态将不可改变,以下例,在调用executor.resolve(3);后,return以前抛出一个异常,promise的状态依旧是fulfilled,终值为3。
new Promise.Builder().promiseHanler(new PromiseHandler(){
@Override
public Object run(PromiseExecutor executor) {
executor.resolve(3);
throw new RuntimeException("error");
return null;
}
}).build()
复制代码
在run方法中executor.resolve(3)等同于return 3
@Override
public Object run(PromiseExecutor executor) {
return 3;
}
复制代码
大多数状况下建议直接使用return返回promise的终值。
将Promise对象的状态从“未完成”变为“失败”(即从pending变为fulfilled)
获取经过new Promise.Builder().externalInput(Object externalInput)
方法注入的参数,具体参考Promise.Builder#externalInput(Object externalInput)
获内部promise的执行结果。经过new Promise.Builder().promise(promise1)指定的promise1的执行结果。具体参考 Promise.Builder#promise(IPromise promise)
fulfilled回调接口
状态转为fulfilled时的回调,返回值能够是IPromise实例或普通对象。若是object是IPromise实例,object做为then方法的返回值,若是object是个普通对象,以object做为终值、状态为fulfilled包装一个新Promise做为then方法的返回值
rejected回调接口
当Promise转变为rejected状态时的回调
rejected回调接口
当发生异常时的回调,最终返回一个Promise或普通对象,若是是一个普通对象,这个对象将做为下一个Promise的终值
当Promise执行结束时的回调(不管是fulfilled仍是rejected)
new Promise.Builder().promiseHanler(new PromiseHandler(){
@Override
public Object run(PromiseExecutor executor) {
executor.resolve(3);//返回异步执行结果3
return null;
}
}).build().then(new OnFulfilledExecutor() {
@Override
public Object onFulfilled(Object resolvedData) {
Integer i = ((Integer)resolvedData)+1;//获取上一个promsie执行结果3,执行+1
System.out.println(i);//输出执行结果4
//建立一个新的promise,将4做为该promise的输入
IPromise p = new Promise.Builder().externalInput(i).promiseHanler(new PromiseHandler() {
@Override
public Object run(PromiseExecutor executor) {
//获取外部输入4
Integer args = (Integer) executor.getExternalInput();
executor.resolve(args*2);//执行 4x2
return null;
}
}).build();
return p;//返回该promise p
}
})
.then(new OnFulfilledExecutor() {//执行p的回调
@Override
public Object onFulfilled(Object args) {
System.out.println(args);//输出p的执行结果
return args;
}
}, new OnRejectedExecutor() {//捕获可能出现的异常
@Override
public void onRejected(Throwable rejectedReason) throws Exception {
rejectedReason.printStackTrace();
}
});
复制代码
结果
4
8
复制代码
ExecutorService fixedPool = Promise.pool(1);//建立一个线程池
//建立promise1
IPromise promise1 = new Promise.Builder().pool(fixedPool).promiseHanler(executor->3).build();
//建立promise2
IPromise promise2 = new Promise.Builder().pool(fixedPool)
.promise(promise1)//让promise2接受promise1的状态,优先执行promise1
.promiseHanler(executor->{
//获取promise1的执行结果,执行promise2的逻辑
return 4+(Integer) executor.getPromiseInput();
})
.build()
.then(resolvedData->{
System.out.println(resolvedData);//打印promise2的执行结果
return resolvedData;
}, rejectedReason-> rejectedReason.printStackTrace());
System.out.println("end");
fixedPool.shutdown();
复制代码
结果
7
end
复制代码
new Promise.Builder().promiseHanler(executor -> 3).build().then(resolvedData->{
System.out.println("a:"+resolvedData);
return new Promise.Builder().promiseHanler(executor -> {
executor.reject(new RuntimeException("err"));//抛出异常
return null;
}).build();
}).then(resolvedData1 -> {//fulfilled回调
System.out.println("b:"+resolvedData1);
return resolvedData1;
},rejectReason -> {//rejected回调
System.err.println("c:"+rejectReason);
});
复制代码
结果
a:3
c:java.lang.RuntimeException: err
复制代码
new Promise.Builder().promiseHanler(executor -> 0).build()
.then(res0->{
System.out.println("a:"+res0);//输出 a:0
Thread.sleep(100);
return 1;//返回1
}).then(res1 -> {
throw new RuntimeException("throw error");//抛出异常
}).then(res2->{
Thread.sleep(100);
System.out.println("b:"+res2);
return 2;
}).pCatch(e->{
Thread.sleep(100);
System.out.println("c:");//输出c:
e.printStackTrace();
return 3;
}).then(res3->{
Thread.sleep(100);
System.out.println("d:"+res3);//输出d:3
return 4;
});
复制代码
结果
a:0
c:
runtimeException:throw error
d:3
复制代码
从上面结果能够看出,在res1出抛出异常后,拒绝了res2处的执行,被pCatch捕获,pCatch返回3,被包装成终值为三、fulfilled状态的promise,在res3打印d:3。
IPromise p1 = new Promise.Builder().promiseHanler(executor -> {
Thread.sleep(1000);
return 1;
}).build();
IPromise p2 = new Promise.Builder().promiseHanler(executor -> {
Thread.sleep(4000);
return 2;
}).build();
IPromise p3 = new Promise.Builder().promiseHanler(executor -> {
Thread.sleep(2000);
return 3;
}).build();
long s = System.currentTimeMillis();
Promise.all(p1,p2,p3).then(resolvedData -> {
Object[] datas = (Object[])resolvedData;
for(Object d:datas){
System.out.println(d);
}
return null;
},e->e.printStackTrace());
System.out.println("耗时:"+(System.currentTimeMillis()-s));
复制代码
结果
1
2
3
耗时:4033
复制代码
Map<String,Boolean> p1Flag = new HashMap<>();
p1Flag.put("flag",true);
IPromise p1 = new Promise.Builder().externalInput(p1Flag).promiseHanler(executor -> {
while (((Map<String,Boolean>)executor.getExternalInput()).get("flag")){
//do something
System.out.println("p1 正在执行任务");
}
System.out.println("p1任务完成,正常结束");
return 1;
}).build();
IPromise p2 = new Promise.Builder().promiseHanler(executor -> {
while (!Thread.currentThread().isInterrupted()){
System.out.println("执行p2正常逻辑");
}
System.err.println("p2线程被取消");
return 2;
}).build();
IPromise p3 = new Promise.Builder().promiseHanler(executor -> {
Thread.sleep(10);
throw new RuntimeException("p3抛出异常");
}).build();
IPromise p4 = new Promise.Builder().finalPromise("4",true).build();
long s = System.currentTimeMillis();
Promise.all(p1,p2,p3,p4).then(resolvedData -> {
Object[] datas = (Object[])resolvedData;
for(Object d:datas){
System.out.println(d);
}
return null;
},e->e.printStackTrace());
System.out.println("耗时:"+(System.currentTimeMillis()-s));
p1Flag.put("flag",false);
复制代码
可能的结果以下
p1 正在执行任务
p1 正在执行任务
执行p2正常逻辑
执行p2正常逻辑
p1 正在执行任务
runtimeException:p3抛出异常
p2线程被取消
p1 正在执行任务
p1 正在执行任务
p1 正在执行任务
p1任务完成,正常结束
复制代码
从上面结果能够看出,开始p1和p2都在正常执行,当p3抛出异常后,Promise.all方法当即返回p3的异常并打印,同时取消p1和p2的执行,因为p2判断了线程状态Thread.currentThread().isInterrupted()
,因此p2执行了正常的退出逻辑。p1仍然在执行,并无被取消掉,最后打印p1任务完成,正常结束是由于程序末尾执行了p1Flag.put("flag",false);
,不然p1会永远循环打印。
public class ThenTest {
public Integer then(int a,int b){
//打印当前执行现场名称
System.out.println(Thread.currentThread().getName());
return a+b;
}
public static void main(String[] args){
//打印主线程名称
System.out.println(Thread.currentThread().getName());
List arg = new ArrayList<>();
arg.add(1);
arg.add(2);
//将ThenTest实例then方法异步执行
Promise.resolve(new ThenTest(),arg).then(resolvedData -> {
System.out.println(resolvedData);
return resolvedData;
}).pCatch(e->{
e.printStackTrace();
return 1;
});
}
}
复制代码
结果
main
promise-thread-0
3
复制代码