JAVA实现async/await异步处理等待机制
搜遍了百度都没看到JAVA有实现async/await的方案,而js 、.net 、scala都有async/await,心里感觉特别不爽,为什么JAVA没有呢,实现async/await很难吗? 于是参考了scala的实现方式,感觉看到了一点希望,觉得java也是可以像scala那样实现的,于是开始了以下尝试: 实现异步等待Async类:
/**
* @author ffychina
* @since 2020-04-13
* https://blog..net/ffychina
* */
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class Async{
private List<AsyncFunction> asyncFnList=new ArrayList<Async.AsyncFunction>();
public Async(){
}
public Async(AsyncFunction runable){
add(runable);
}
public Async add(AsyncFunction runable){
asyncFnList.add(runable);
return this;
}
public Object await(){
CountDownLatch latch=new CountDownLatch(asyncFnList.size());
for(AsyncFunction asyncFn:asyncFnList){
asyncFn._latch[0]=latch;
Thread thread=new Thread(asyncFn);
thread.start();
}
try{
latch.await();
}catch(InterruptedException e){
e.printStackTrace();
}
List result=this.asyncFnList.get(0)._result;
if(asyncFnList.size()==0){
return result.get(0);
}else{
return result.toArray();
}
}
@FunctionalInterface
public static interface AsyncFunction extends Runnable{
Object call();
List _result=new ArrayList();
CountDownLatch[] _latch=new CountDownLatch[1];
@Override
default void run(){
synchronized(_result){
_result.add(call());
}
_latch[0].countDown();
}
default Object result(){
return _result.toArray(new Object[0]);
}
}
}
异步线程测试用例:
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import org.nutz.http.Http;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
TimeInterval timer=DateUtil.timer();
Object result=new Async(()->{
int courseId=Double.valueOf(Math.random()*100000).intValue();
String url="http://127.0.0.1:8080/hello/"+courseId;
String res=Http.get(url).getContent();
log.info(res);
return res;
}).add(()->{
//增加多一个异步线程
String url="http://127.0.0.1:8080/hello/world";
String res=Http.get(url).getContent();
log.info(res);
return res;
}).await();
log.info(StrUtil.join(",",result));
log.info("finish test,spend ms: "+timer.interval());
异步线程处理结果:
20-04-13 09:42:57.194 INFO [Thread-0] {
"method":"post","param1":"hello","param2":"16686"}
20-04-13 09:42:57.196 INFO [Thread-1] {
"method":"post","param1":"hello","param2":"world"}
20-04-13 09:42:57.206 INFO [main] {
"method":"post","param1":"hello","param2":"16686"},{
"method":"post","param1":"hello","param2":"world"}
20-04-13 09:42:57.207 INFO [main] finish test,spend ms: 452
分享心得: 以上代码实现只是为了抛砖引玉,希望大家都给点建议或加以完善。我的出发点是在使用vertx框架时能更好的利用异步处理,写出更容易阅读和理解的代码风格。 另外,如何更好地结合Promise目前还没有想好该怎么做,也希望能听一下大家的建议。
