java多线程异步

背景

最近遇到多数据库执行sql处理后生成报表,项目原有逻辑是单线程同步执行的,随着数据量的增大时间越来越长,我忍不住要优化。考虑一定得用多线程处理,那就首先需要线程池了,毕竟没有线程池的情况下很容易出现无休止创建线程是非常危险的。

实现

代码

伪代码

//创建线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
CompletionService<Object> completionSevice = new ExecutorCompletionService<Object>(executor);

for (DatabaseNode databaseNode: databaseNodeList) {
    //提交请求到具体的库
     completionSevice.submit(new SqlHandler(properties, databaseNode, sql,         
     ModuleConstant.NODE_PASSWORD_KEY, encode, userType));

}


//获取执行结果
//databaseNodeList.size()只为获取节点个数,获取到的每个节点是没有顺序
 for (int i = 0; i < databaseNodeList.size(); i++) {
    Object result = null;
    DrdsNodes nodeSchema = null;
    //获取到每个库节点执行的结果,结果是从最先执行完的开始拿的,每次拿一个
    Map<DrdsNodes, Object> resultMap = (Map<DatabaseNode , Object>) 
          completionSevice.take().get();
  //后续根据具体业务操作
   。。。。

 }


/**
  *具体执行sql的类  (伪代码)
  *
 */
public class SqlHandler  implements Callable<Object> {
	
	private final String ddl;
	private JdbcTemplate jdbcTemplate;
    private DrdsNodes databaseNode;
	
	public SqlRowNumHandler(RdsProperties properties, DatabaseNode databaseNode, String ddl, String nodePwdKey,String encode, Integer userType) {
		
       //sql的构建封装代码

	}
	
   //类实现Callable<Object>,初始化时自动调用此方法
	@Override
    public Object call() throws Exception {
       //key 是数据库的实例,用以获取时区分是哪个库执行的结果
        Map<DrdsNodes, Object> resultMap = Maps.newHashMap();
        try {
            Object value = jdbcTemplate.update(ddl);
            resultMap.put(drdsNode, value);
            return resultMap;
        } catch (Exception e) {
            resultMap.put(drdsNode, e.getMessage());
            return resultMap;
        }
    }

注:completionSevice.take().get();是类似于指针一样获取结果(先执行完返回的先获取到)

CompletionService实现原理

CompletionService实际上可以看做是Executor和BlockingQueue的结合体。CompletionService在接收到要执行的任务时,通过类似BlockingQueue的put和take获得任务执行的结果。CompletionService的一个实现是ExecutorCompletionService,ExecutorCompletionService把具体的计算任务交给Executor完成。

测试后发现效率提高了5倍左右。

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值