Java实现Promise.all()的示例代码
JavaScript的Promise.all()
Promise是JavaScript异步编程的一种解决方案,在ES6中引入。
通过Promise.all()可以实现对一组异步请求的统一处理,等待所有异步执行完成之后调用回调函数。
其实,这种并发执行同步等待的需求在Java并发编程中也很常见,那么,是否可以通过Java也来实现这样一个Promise类呢?
使用Java实现Promise.all()
使用工具
CountDownLatch:Java并发工具包中有CountDownLatch类允许一个或多个线程等待其他线程的一系列操作完成。
ThreadPoolExecutor:通过线程池实现多线程的并发执行
实现
publicclassPromise{
privatestaticExecutorServiceexecutorService=Executors.newScheduledThreadPool(16);
privatePromise(){
thrownewAssertionError();
}
/**
*实现并发同时地对某个action并发执行并返回执行结果
*实现思路:
*并发创建所有执行的线程,并通过锁(start)阻塞等待着
*在创建所有执行的线程后(ready)开始计时,并解锁然所有的线程启动
*通过另外一个锁(done)记录执行完的线程
*主线程只需关心3点
*-所有线程是否准备好
*-准备好的话开始计时并解锁开始执行
*-等待执行完毕
*
*@paramcallableList要并发执行的列表
*@returnlist执行结果,list.item为null的话表示执行异常
*@throwsInterruptedException异常
*/
publicstaticListall(finalList>callableList)throwsInterruptedException{
finalListresult=newArrayList<>();
intlength=callableList.size();
finalCountDownLatchready=newCountDownLatch(length);
finalCountDownLatchstart=newCountDownLatch(1);
finalCountDownLatchdone=newCountDownLatch(length);
for(finalCallablecallable:callableList){
executorService.execute(newRunnable(){
@Override
publicvoidrun(){
ready.countDown();
try{
start.await();
Tt=callable.call();
result.add(t);
}catch(Exceptione){
//interruptwhenexception
Thread.currentThread().interrupt();
//setnullmeanexception
result.add(null);
e.printStackTrace();
}finally{
done.countDown();
}
}
});
}
ready.await();
longstartnano=System.nanoTime();
start.countDown();
done.await();
longcause=System.nanoTime()-startnano;
System.out.println(String.format("Promisealldone,causetimemillSecond:%s",cause/1000000));
returnresult;
}
}
效果
测试
publicvoidpromiseAllTest()throwsException{
List>callables=newArrayList<>();
for(inti=0;i<10;i++){
intfinalI=i;
callables.add(newCallable(){
@Override
publicStringcall()throwsException{
intmillis=newRandom().nextInt(10000);
Thread.sleep(millis);
System.out.println(String.format("thread%ssleep%smillis",finalI,millis));
return"Thread"+finalI;
}
});
}
Listresult=Promise.all(callables);
System.out.println(result);
System.out.println("done...");
}
测试结果
thread1sleep732millis
thread2sleep758millis
thread7sleep976millis
thread8sleep1397millis
thread5sleep1513millis
thread0sleep2221millis
thread3sleep4885millis
thread6sleep5221millis
thread4sleep7101millis
thread9sleep7634millis
Promisealldone,causetimemillSecond:7638
[Thread1,Thread2,Thread7,Thread8,Thread5,Thread0,Thread3,Thread6,Thread4,Thread9]
done...
总结
本文只是通过原生Java实现简单版本的Promise.all(),可用于简单的并发编程,但是对于实际高并发应用还需要优化,如对线程池的优化,还有中断的处理等。
参考
《EffectiveJava》第二版第十章第69条:并发工具优先于wait和notify
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。