天天看点

在Java线程池中 主线程等待子线程完成任务 并返回创建一个固定长度的线程池执行业务逻辑完成

Java

  • 创建一个固定长度的线程池
  • 执行业务逻辑
  • 完成

创建一个固定长度的线程池

/**
     * <pre>
     * Create By Liu Tao
     * 创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。
     * 在任何时候,大多数Threads线程都是活动的处理任务。
     * 如果在所有线程都处于活动状态时提交其他任务,它们将在队列中等待,直到线程可用为止。
     * 如果任何线程在关闭之前的执行过程中由于失败而终止,那么如果需要执行后续任务,则会替换一个新线程。
     * 池中的线程将一直存在,直到显式关闭为止。
     * </pre>
     * @date 2019-07-08 22:53
     * @param
     * @return
     */
    private static   ExecutorService executorService = Executors.newFixedThreadPool(40);

           

执行业务逻辑

1, 业务类型: 和DB进行操作时,由于数据库中有百万条数据,我要将他们按条件查询出来并汇总到三个List中 。
然后再进一步按条件区分,汇总 最后合并传递给前台. 每次查询大约为30秒 。于是考虑用线程去执行逻辑,提高用户体验。
           

···

@Override
public ResultData<?> getBuildingBusiness(String id,List<String> areaIds,List<String> bureaus,Pageable pageable) throws Exception {
		//查询出来的数据会赋值给 specialEntityList 
		List<SpecialEntity> specialEntityList = new ArrayList<>();
		//添加一个计数器
		final CountDownLatch countDownLatch = new CountDownLatch(specialEntityList .size());
		//此处使用的是 JDK 1.8的 lambda语法
		 motorList.forEach(item ->{
		 			//此处用的也是Jdk 1.8的lambda语法执行的线程池  非lambda请看下图
		            executorService.execute(() -> {
		                try {
		        			// 利用线程池的优点来执行你的业务逻辑
		        			// 优点大概有:1,更好的资源利用性。2,在某些情况下更简单的程序设计。3,程序的响应性更强。
		                }catch (Exception ex){
		                    log.error("执行[XXX]查询数据时异常,异常内容{},异常信息:{},", ex.getMessage(),ex);
		                    ex.printStackTrace();
		                }finally {
		
		                    //减少计数,如果计数为 zero  the child thread shutdown....
		                    countDownLatch.countDown();
		                }
		            });
		        });
		        
		        //当前主线程等待子线程的锁计数器为0时,则主线程继续..
		        countDownLatch.await();
		
		        log.info("线程 {} 执行完毕,正在回收线程...",Thread.currentThread().getName());
		        
	return ResultData.success(motorRoomList.getTotalElements(),returnMap);
           

非lambda表达式的线程池执行的语法

在Java线程池中 主线程等待子线程完成任务 并返回创建一个固定长度的线程池执行业务逻辑完成

完成

继续阅读