赞
踩
天下风云出我辈,一入编程岁月催。
我们使用线程的时候就去创建一个线程,这样实现起来非常简单,但是会有一个问题,如果并发的线程数量很多,并且每一个线程都是执行一个很短的任务就结束了,这样频繁的创建线程就会大大降低系统的效率,因为频繁的创建和销毁都需要时间。这样我们就需要一个可复用就是这个线程执行完成一个任务之后,不会被销毁,继续执行其他的任务。在java中线程池可以达到这样的效果。
比较重要的几个类:
ExecutorService | 真正的线程池接口。 |
---|---|
ScheduledExecutorService | 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。 |
ThreadPoolExecutor | ExecutorService的默认实现。 |
ScheduledThreadPoolExecutor | 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。 |
代码如下(示例):
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
设置线程池的参数的方法 :
一种说法,是线程数和cpu数有关系
当应用是IO密集型时,线程数T=2N+1.
当应用是CPU密集型时, 线程数T=N+1
一种说法是,线程池的的设置跟实际的并发量有关系
尽量是两种方法结合起来使用,适合自己业务场景的才是最适合的
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize-池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute方法提交的 Runnable任务。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
项目需求(示例):用线下的excel新建订单
项目分析:excel量比较大,而且基础数据还要请求基础资料系统,io比较频繁,所以采用了多线程的方式
思路:首先解析excel放入内存,然后拿到这部分数据请求基础资料系统进行拼接形成完整的javabean然后插入数据库
List<List<DiscountDto>> splitList = ListWrapUtils.split(template, 500); List<OrderDetailWrap> orderDetailWraps = Lists.newArrayListWithCapacity(template.size()); List<TaskWithResult> collect = new ArrayList<>(); for (int i = 0; i < splitList.size(); i++) { collect.add(new TaskWithResult(String.valueOf(i), splitList.get(i))); } List<Future<Result>> futures = executorService.invokeAll(collect); Map<String, Result> resultMap = futures.stream().map(e -> { try { return e.get(); } catch (InterruptedException | ExecutionException ex) { logger.msg("ioExecutorService执行异常!").exception(ex).error(); } throw new SystemException("ioExecutorService执行异常!"); }).collect(Collectors.toList()).stream().collect(Collectors.toMap(Result::getId, Function.identity()));
protected class TaskWithResult implements Callable<Result> { /** * 数据片id */ private String id; private List<? extends AbstTitle> slice; public TaskWithResult(String id, List<? extends AbstTitle> slice) { this.id = id; this.slice = slice; } @Override public Result call() { Set<GetSkusByProductCodeAndSizeReqeustVo> request = slice.stream().map(t -> new GetSkusByProductCodeAndSizeReqeustVo(t.getProductCode(), t.getSizeDetailValue())) .collect(Collectors.toSet()); Optional<List<ProductBaseDto>> response = pdcClientFacade.getSkusByProductCodesAndSize(request); return response.map(productBaseDtos -> new Result(id, true, productBaseDtos)) .orElseGet(() -> new Result(id, false, Collections.emptyList())); } }
提示:。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。