Java并发:Callable与Future的应用 多线程查询

12 篇文章 0 订阅
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_33556185/article/details/77018370

   我们都知道实现多线程有2种方式,一种是继承Thread,一种是实现Runnable,但这2种方式都有一个缺陷,在任务完成后无法获取返回结果。要想获得返回结果,就得使用Callable,Callable任务可以有返回值,但是没法直接从Callable任务里获取返回值;想要获取Callabel任务的返回值,需要用到Future。所以Callable任务和Future模式,通常结合起来使用。

试想一个场景:需要一个帖子列表接口,除了需要返回帖子列表之外,还需要返回每条帖子的点赞列表和评论列表。一页10条帖子来计算,这个接口需要访问21次数据库,访问一次数据库按100ms计算,21次,累计时间为2.1s。这个响应时间,怕是无法令人满意的。怎么办呢?异步化改造接口。

查出帖子列表后,迭代帖子列表,在循环里起10个线程,并发去获取每条帖子的点赞列表,同时另起10个线程,并发去获取每条帖子的评论列表。这样改造之后,接口的响应时间大大缩短,在200ms。这个时候就要用Callabel结合Future来实现。

private List<PostResponse> createPostResponseList(Page<PostResponse> page,final String userId){
		if(page.getCount()==0||page==null||page.getList()==null){
			return null;
		}
		//获取帖子列表
		List<PostResponse> circleResponseList = page.getList();
		int size=circleResponseList.size();
		ExecutorService commentPool = Executors.newFixedThreadPool(size);
		ExecutorService supportPool = Executors.newFixedThreadPool(size);
		try {
			List<Future> commentFutureList = new ArrayList<Future>(size);
			if (circleResponseList != null && circleResponseList.size() > 0) {
				for (PostResponse postResponse : circleResponseList) {
					final String circleId=postResponse.getId();
					final String postUserId=postResponse.getUserId();
					//查评论列表
					Callable<List<CircleReviews>> callableComment = new Callable<List<CircleReviews>>() {
						@Override
						public List<CircleReviews> call() throws Exception {
							return circleReviewsBiz.getPostComments(circleId);
						}
					};
					Future f = commentPool.submit(callableComment);
					commentFutureList.add(f);
					//查点赞列表
					Callable<List<CircleZan>> callableSupport = new Callable<List<CircleZan>>() {
						@Override
						public List<CircleZan> call() throws Exception {
							return circleZanBiz.findList(circleId);
						}
					};
					Future supportFuture = supportPool.submit(callableSupport);
					commentFutureList.add(supportFuture);
				}
 
			}
			// 获取所有并发任务的执行结果
			int i = 0;
			PostResponse temp = null;
			for (Future f : commentFutureList) {
				temp = circleResponseList.get(i);
				temp.setCommentList((List<CircleReviews>) f.get();
				temp.setSupportList((List<CircleZan>) f.get();
				circleResponseList.set(i, temp);
				i++;
			}
 
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭线程池
			commentPool.shutdown();
			supportPool.shutdown();
		}
		return circleResponseList;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值