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目前还没有想好该怎么做,也希望能听一下大家的建议。

经验分享 程序员 微信小程序 职场和发展