ThreadPoolTaskExecutor实现多线程并处理返回值

使用executor.execute(Runnable task)方法

思路:事先定义一个存放结果的集合(必须是线程安全的集合),作为参数传到多线程任务中,每个任务执行后把需要返回的结果放在集合中。

这样在执行完成后就可以访问这个集合拿到返回值。但是还有一个问题:

怎么保证当我们访问集合时任务都已经执行完成保证不会丢失某一条任务的执行结果呢????

必须是线程安全的集合所以这里就要使用java.util.concurrent包下的CountDownLatch类,保证多线程全部执行完毕后再进行后续操作。实现的原理其实就是计数器类型的同步锁。
new CountDownLatch(50):初始化数量

latch.countDown():任务执行完成,数量减1

latch.await();等待,不断检测数量是否为0,为零是执行后面的操作

final CountDownLatch latch=new CountDownLatch(3);//定义多线程数量,一般就是任务数量
                        threadPoolTaskExecutor.execute(()->{
                            try {
                                Thread.sleep(1);
                                //商品搜索结果
                                List<ProductHomeSearchVO> products = this.siteSearchGoods(keyWord);
                                log.info("HomeServiceImpl.siteSearch:商品搜索结果{}条",products==null?"0":products.size());
                                //商品VO
                                resultMap.put(SearchStatusEnum.Insurance_Products.getCode(), products);
                            } catch (InterruptedException e) {
                                log.info("查询商品报错",e.getMessage());
                            }finally{
                                latch.countDown();//每个任务执行完成后对数量进行减一操作
                            }

                        });

                        threadPoolTaskExecutor.execute(()->{
                            try {
                                Thread.sleep(1);
                                //保险知道搜索
                                PageInfo<NewsVO> knowledgePageInfo = new PageInfo<>();
                                this.queryNewsVOList(keyWord,knowledgePageInfo,SearchStatusEnum.Insurance_Knowledge.getCode());
                                //保险知道VO
                                synchronizedlist.addAll(knowledgePageInfo.getList());
                                resultMap.put(SearchStatusEnum.Insurance_Knowledge.getCode(), knowledgePageInfo);
                            } catch (InterruptedException e) {
                                log.info("查询保险知道",e.getMessage());
                            }finally{
                                latch.countDown();//每个任务执行完成后对数量进行减一操作
                            }

                        });

                        threadPoolTaskExecutor.execute(()->{
                            try {
                                Thread.sleep(1);
                                //保险服务搜索
                                PageInfo<NewsVO> servicePageInfo = new PageInfo<>();
                                this.queryNewsVOList(keyWord,servicePageInfo,SearchStatusEnum.Insurance_Service.getCode());
                                //保险知道VO
                                synchronizedlist.addAll(servicePageInfo.getList());
                                resultMap.put(SearchStatusEnum.Insurance_Service.getCode(), servicePageInfo);

                            } catch (InterruptedException e) {
                                log.info("查询保险服务",e.getMessage());
                            }finally{
                                latch.countDown();//每个任务执行完成后对数量进行减一操作
                            }

                        });

                        latch.await();//等待,不断检测数量是否为0,为零是执行后面的操作

                        //处理参数
                        if (null != resultMap.get(SearchStatusEnum.Insurance_Products.getCode()) &&
                                CollectionUtils.isNotEmpty((List<ProductHomeSearchVO>)resultMap.get(SearchStatusEnum.Insurance_Products.getCode()))){
                            List<ProductHomeSearchVO> productVo = (List<ProductHomeSearchVO>)resultMap.get(SearchStatusEnum.Insurance_Products.getCode());
                            homeSearchVO.setProducts(productVo);
                        }
                        if (null != resultMap.get(SearchStatusEnum.Insurance_Knowledge.getCode()) &&
                                CollectionUtils.isNotEmpty(((PageInfo<NewsVO>)resultMap.get(SearchStatusEnum.Insurance_Knowledge.getCode())).getList())){
                            PageInfo<NewsVO> knowledgePageInfo = (PageInfo<NewsVO> )resultMap.get(SearchStatusEnum.Insurance_Knowledge.getCode());
                            homeSearchVO.setKnowledgePageInfo(knowledgePageInfo);
                        }
                        if (null != resultMap.get(SearchStatusEnum.Insurance_Service.getCode()) &&
                                CollectionUtils.isNotEmpty(((PageInfo<NewsVO>)resultMap.get(SearchStatusEnum.Insurance_Service.getCode())).getList())){
                            PageInfo<NewsVO> servicePageInfo = (PageInfo<NewsVO> )resultMap.get(SearchStatusEnum.Insurance_Service.getCode());
                            homeSearchVO.setServicePageInfo(servicePageInfo);
                        }

                        //热门搜索记录
                        if (StringUtils.isNotBlank(keyWord) &&
                                (CollectionUtils.isNotEmpty(homeSearchVO.getProducts())
                                        || CollectionUtils.isNotEmpty(synchronizedlist))){
                            //热门搜索词汇量
                            Long count = redisService.zcard(FaceWebCommonConstants.POPULAR_SEARCHES);
                            if (count>-1 && count<11){
                                redisService.zinCrBy(FaceWebCommonConstants.POPULAR_SEARCHES, keyWord,1.0 );
                            }
                            redisService.set(FaceWebCommonConstants.POPULAR_SEARCHES+keyWord, JSONObject.toJSONString(homeSearchVO), 60*60);
                        }
                        log.info("homeSearchVO{}",JSON.toJSONString(homeSearchVO));
                        resultDTO.setData(homeSearchVO);
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中可以使用ThreadPoolTaskExecutor实现多线程处理批量数据入库的操作。ThreadPoolTaskExecutor是Spring框架提供的一个线程池实现类,可以方便地管理线程池的创建和销毁,并提供了一些配置参数来控制线程池的行为。 下面是使用ThreadPoolTaskExecutor实现多线程处理批量数据入库的步骤: 1. 首先,需要在项目中引入Spring的依赖,以使用ThreadPoolTaskExecutor类。可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> ``` 2. 在代码中创建一个ThreadPoolTaskExecutor对象,并进行相关配置。可以通过在Spring配置文件中配置bean,或者使用Java代码进行配置。以下是一个示例配置: ```java @Configuration @EnableAsync public class ThreadPoolConfig { @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); // 设置核心线程数 executor.setMaxPoolSize(20); // 设置最大线程数 executor.setQueueCapacity(100); // 设置队列容量 executor.setThreadNamePrefix("MyThread-"); // 设置线程名前缀 executor.initialize(); // 初始化线程池 return executor; } } ``` 3. 在需要进行批量数据入库的地方,使用@Async注解标记方法,并指定使用的线程池。例如: ```java @Service public class DataBatchService { @Autowired private ThreadPoolTaskExecutor taskExecutor; @Async("taskExecutor") public void processBatchData(List<Data> dataList) { // 批量数据入库的逻辑处理 // ... } } ``` 4. 调用processBatchData方法时,会自动使用线程池中的线程进行处理。例如: ```java @Autowired private DataBatchService dataBatchService; public void batchDataInsert(List<Data> dataList) { dataBatchService.processBatchData(dataList); } ``` 这样就可以利用ThreadPoolTaskExecutor实现多线程处理批量数据入库了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值