springboot多线程

1,004 阅读1分钟

1.创建多线程配置 AsyncTaskConfig

blog.csdn.net/qqzhengwei/…

@Configuration
@EnableAsync
public class AsyncTaskConfig implements AsyncConfigurer {

    @Override
    @Bean
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        //设置核心线程数
        threadPool.setCorePoolSize(10);
        //设置最大线程数
        threadPool.setMaxPoolSize(15);
        //线程池所使用的缓冲队列
        threadPool.setQueueCapacity(20);
        //等待任务在关机时完成--表明等待所有线程执行完
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止
        threadPool.setAwaitTerminationSeconds(60);
        //  线程名称前缀
        threadPool.setThreadNamePrefix("mds-async-task-");
        // 初始化线程
        threadPool.initialize();
        return threadPool;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }

}

2.创建异步多线程接口和实现类

public interface IZhiyiAsyncService {
    /**
     * 异步保存4、商品最新属性
     * @param limit
     * @param offset
     * @return
     */
    Future<Integer> saveItemPropertyAsync(int limit,int offset);
}
/**
 * 4.异步保存商品属性
 * @param limit
 * @param offset
 * @return
 */
@Async
@Override
public Future<Integer> saveItemPropertyAsync(int limit,int offset) {
    log.info("limit={} offset={}", limit, offset);
    int exeCount = 0;
    List<ZhiyiShop> shopList = this.findZhiyiShopPage(limit, offset);
    for (ZhiyiShop shop : shopList) {
        int pageNo = 1;
        int pageSize = 200;
        log.info("开始 5、获取商品昨日最新属性 shopId={},每页数量={}", shop.getShopId(), pageSize);
        while (pageNo > 0) {
            String reqUrl = String.format("%s/item-property?account=%s&appcode=%s&shopId=%s&pageNo=%d&pageSize=%d", zhiyiUrl, zhiyiAccount, zhiyiApppcode, shop.getShopId(), pageNo, pageSize);
            log.info(reqUrl);
            ParameterizedTypeReference<ZhiyiRsp<ZhiyiPageDto<List<ZhiyiItemProperty>>>> reference = new ParameterizedTypeReference<ZhiyiRsp<ZhiyiPageDto<List<ZhiyiItemProperty>>>>() {
            };
            ResponseEntity<ZhiyiRsp<ZhiyiPageDto<List<ZhiyiItemProperty>>>> entity = restTemplate.exchange(reqUrl, HttpMethod.GET, null, reference);
            ZhiyiRsp<ZhiyiPageDto<List<ZhiyiItemProperty>>> rsp = entity.getBody();
            if (rsp.getResult() == null || CollectionUtils.isEmpty(rsp.getResult().getResultList())) {
                pageNo = 0;
            } else {
                pageNo++;
                List<Object> ids = new ArrayList<>();
                for (ZhiyiItemProperty item : rsp.getResult().getResultList()) {
                    ids.add(item.getId());
                }
                zhiyiMapper.commonDelete("zhiyi_item_property", "id", ids);
                exeCount += zhiyiItemPropertyMapper.insertBatch(rsp.getResult().getResultList());
            }
        }
        log.info("结束 5、获取商品昨日最新属性 shopId={},每页量={},成功行数={}",shop.getShopId(),pageSize, exeCount);
    }
    return new AsyncResult<>(exeCount);
}

3.调用多线程

@Slf4j
@Service
public class ZhiyiServiceImpl {  

    /**
     * 4、获取商品昨日最新属性
     * @return
     */
    @SneakyThrows
    @Override
    public Integer saveItemProperty() {
        int exeCount=0;
        int totalCount=zhiyiMapper.findCount("zhiyi_shop");
        //开启5个线程,分成5页
        int totalPage=5;
        int limit = (int) Math.ceil(totalCount / Double.valueOf(totalPage));
        List<Future> futureList=new ArrayList<>();
        for(int i=0;i<totalPage;i++) {
            futureList.add(zhiyiAsyncService.saveItemPropertyAsync(limit,Math.min(i*limit,totalCount) ));
        }
        for (Future<Integer> future : futureList) {
            while (true) {
                if (future.isDone() && !future.isCancelled()) {
                    exeCount+=future.get();
                    log.info("5、获取商品昨日最新属性 完成线程任务 ,总行数={}",future.get() );
                    break;
                } else {
                    Thread.sleep(1);
                }
            }
        }
        return exeCount;
    }

  
}