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异常 */ publicstaticList all(finalList >callableList)throwsInterruptedException{ finalList result=newArrayList<>(); intlength=callableList.size(); finalCountDownLatchready=newCountDownLatch(length); finalCountDownLatchstart=newCountDownLatch(1); finalCountDownLatchdone=newCountDownLatch(length); for(finalCallable callable: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; } }); } List result=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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。