Spring中线程池的使用
<bean id="threadPoolTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数,默认为1 -->
<property name="corePoolSize" value="5" />
<!-- 最大线程数,默认为Integer.MAX_VALUE -->
<property name="maxPoolSize" value="10" />
<!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE
<property name="queueCapacity" value="1000" /> -->
<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="300" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->
<property name="rejectedExecutionHandler">
<!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->
<!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 -->
<!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
<!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
然后定义一个component组件,然后线程的引用就十分简单了,只要把这个线程扔进这个线程池子就行了
package com.digitalpublishing.sage.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import org.springframework.stereotype.Component;
import com.digitalpublishing.module.sage.PJournal;
import com.digitalpublishing.sage.dao.AcLogCounterWebMapper;
/**
* @ClassName: CounterWebJr1
* @Description: webJr1统计数据查询
* @author wd
* @date 2018年12月26日 上午9:22:20
*
*/
@Component
public class CounterWebJr1 implements Callable< ArrayList<Object[]>> {
private AcLogCounterWebMapper acLogCounterWebMapper;
private List<PJournal> journalList;
private String accountId;
private String startTime;
private String endTime;
private List<String> dateHeader;
public void setAcLogCounterWebMapper(AcLogCounterWebMapper acLogCounterWebMapper) {
this.acLogCounterWebMapper = acLogCounterWebMapper;
}
public void setJournalList(List<PJournal> journalList) {
this.journalList = journalList;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public void setDateHeader(List<String> dateHeader) {
this.dateHeader = dateHeader;
}
@Override
public ArrayList<Object[]> call() throws Exception {
ArrayList<Object[]> rows = new ArrayList<>();
// 根据机构ID 刊ID 年月 查询对应的记录
for (PJournal journal : journalList) {
String journalId = journal.getMdcProJournalId();
// 以 年月 TYPE 分类
List<Map<String, String>> list = acLogCounterWebMapper.getLogCounterJr1(accountId, journalId, startTime,
endTime);
List<String> content = new ArrayList<>();
content.add(journal.getTitle());
content.add("SAGE Publications");
content.add("SAGE Journals");
content.add("10.1177/" + journal.getFla());
content.add(journal.getFla());
content.add(journal.getIssn());
content.add(journal.getEissn());
int total = 0;// 一个刊统计时间段内的总数
int html = 0;// 一个刊统计时间段内的html总数
int pdf = 0;// 一个刊统计时间段内的pdf总数
// 每个刊每个月的访问数
Map<String, String> mapC = new HashMap<String, String>();
if (list.isEmpty()) {
// 未查询出记录则直接赋值为0
content.add(String.valueOf(total));
content.add(String.valueOf(html));
content.add(String.valueOf(pdf));
for (int i = 0; i < dateHeader.size(); i++) {
content.add("0");
}
} else {
// 有记录的可能会存在一个月内不同TYPE的两条记录
for (Map<String, String> map : list) {
// 月份
String time = (String) map.get("LOGTIME");
// 类型 3 4
String type = map.get("TYPE");
// 访问数
String num = map.get("C");
// 刊 时间段内访问总数
total += Integer.valueOf(num);
// 刊时间段内 PDF 和 HTML 访问数 && PDF,HTML所有访问数
if ("3".equals(type)) {
pdf += Integer.valueOf(num);
}
if ("4".equals(type)) {
html += Integer.valueOf(num);
}
if (mapC.containsKey(time)) {
String val = mapC.get(time);
mapC.put(time, String.valueOf(Integer.valueOf(val) + Integer.valueOf(num)));
} else {
mapC.put(time, num);
}
}
content.add(String.valueOf(total));
content.add(String.valueOf(html));
content.add(String.valueOf(pdf));
for (String key : dateHeader) {
if (mapC.containsKey(key)) {
content.add(mapC.get(key));
} else {
content.add("0");
}
}
}
rows.add(content.toArray());
}
return rows;
}
}
最后在你所需要的地方就可以调用这个组件了,不论是service还是controller都行
List<Future<ArrayList<Object[]>>> results = new ArrayList<Future<ArrayList<Object[]>>>(10);
List<List<PJournal>> splitList = ListUtils.averageAssign(journalList, 10);
for (List<PJournal> list : splitList) {
CounterWebJr1 ct = new CounterWebJr1();
ct.setAcLogCounterWebMapper(acLogCounterWebMapper);
ct.setAccountId(accountId);
ct.setDateHeader(dateHeader);
ct.setStartTime(startTime);
ct.setEndTime(endTime);
ct.setJournalList(list);
Future<ArrayList<Object[]>> future = threadPoolTaskExecutor.submit(ct);
results.add(future);
}
for (Future<ArrayList<Object[]>> future : results) {
ArrayList<Object[]> arrayList = future.get();
rows.addAll(arrayList);
}
Spring中线程池的使用的更多相关文章
- Spring中线程池的应用
多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了Java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说 ...
- Spring Boot 线程池
参考 SpringBoot 线程池 程序猿DD-Spring Boot使用@Async实现异步调用:自定义线程池 如何优雅的使用和理解线程池 Spring Boot线程池的使用心得 博客园-Sprin ...
- Java中java.util.concurrent包下的4中线程池代码示例
先来看下ThreadPool的类结构 其中红色框住的是常用的接口和类(图片来自:https://blog.csdn.net/panweiwei1994/article/details/78617117 ...
- Spring集成线程池
自己在程序中手动New很容易造成线程滥用,创建线程也是比较消耗资源的操作,所以建议如果有此需求,将线程池统一交给Spring框架进行管理. 如下: <!--Spring 集成线程池,不允许自己开 ...
- spring @Async 线程池使用
最近公司项目正逐渐从dubbo向springCloud转型,在本次新开发的需求中,全部使用springcloud进行,在使用时线程池,考虑使用spring封装的线程池,现将本次使用心得及内容记录下来 ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- Java并发编程中线程池源码分析及使用
当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...
- 沉淀再出发:java中线程池解析
沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...
- Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor
原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...
随机推荐
- python 基础(十) 面向对象
面向对象 一.概念 类(class): 用来描述具有相同属性和方法的对象的集合 对象是类的实例化 类变量:类变量在整个实例化的对象中是共用的.定义在类中 并且是函数体外的 实例变量:只能作用于 当前类 ...
- Qt 进程和线程之四:线程实际应用
为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程.对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题. 大多数情况下, ...
- elasticsearch的模糊查询
https://blog.csdn.net/a772304419/article/details/78951561
- 记住,永远不要在MySQL中使用“utf8”-转
http://www.infoq.com/cn/articles/in-mysql-never-use-utf8-use-utf8 最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的M ...
- div 绝对定位
div绝对居下 .Phone2title{ width:%; height:30px; line-height:30px; /*text-align:left;*/ /*background-colo ...
- 2019/05/11 JAVA虚拟机原理
所谓虚拟机,就是一台虚拟的机器.他是一款软件,用来执行一系列虚拟计算指令,大体上虚拟机可以分为 系统虚拟机和程序虚拟机, 大名鼎鼎的Visual Box.Vmare就属于系统虚拟机,他们完全是对物理计 ...
- UIView动画效果之----翻转.旋转.偏移.翻页.缩放.取反的动画效
翻转的动画 //开始动画 [UIView beginAnimations:@"doflip" context:nil]; //设置时常 [UIView setAnimationDu ...
- springMVC 中 ajax get 请求和 post 请求的坑以及参数传递
1, ajax 请求 无论为 post ,或者 get ,url中带有?形式的参数,后台都能以String类型变量接收,变量名称和参数名称必须一致 前台ajax: $.ajax( "prod ...
- shell批量转换iOS和Android图标
icon_ios.sh #!/bin/sh convert icon-1024.png -resize 180x180 icon-180@3x.png convert icon-1024.png -r ...
- ansible 调优
1.设置ssh长链接ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d 2.开启pipelining开启pipelining 需要被控制机 ...