<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中线程池的使用的更多相关文章

  1. Spring中线程池的应用

    多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了Java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说 ...

  2. Spring Boot 线程池

    参考 SpringBoot 线程池 程序猿DD-Spring Boot使用@Async实现异步调用:自定义线程池 如何优雅的使用和理解线程池 Spring Boot线程池的使用心得 博客园-Sprin ...

  3. Java中java.util.concurrent包下的4中线程池代码示例

    先来看下ThreadPool的类结构 其中红色框住的是常用的接口和类(图片来自:https://blog.csdn.net/panweiwei1994/article/details/78617117 ...

  4. Spring集成线程池

    自己在程序中手动New很容易造成线程滥用,创建线程也是比较消耗资源的操作,所以建议如果有此需求,将线程池统一交给Spring框架进行管理. 如下: <!--Spring 集成线程池,不允许自己开 ...

  5. spring @Async 线程池使用

    最近公司项目正逐渐从dubbo向springCloud转型,在本次新开发的需求中,全部使用springcloud进行,在使用时线程池,考虑使用spring封装的线程池,现将本次使用心得及内容记录下来 ...

  6. Java中线程池,你真的会用吗?

    在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...

  7. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  8. 沉淀再出发:java中线程池解析

    沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...

  9. Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor

    原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...

随机推荐

  1. Flask (六) 项目(淘票票)

    FlaskDay06 Flask项目-淘票票 RESTful REST一种软件架构风格.设计风格.而不是标准,只是提供了一组设计原则和约束条件.它主要用户客户端和服务器交互类的软件. ​ 在前后端分离 ...

  2. Python常用模块之hashlib(加密)

    Python常用模块之hashlib(加密) Python里面的hashlib模块提供了很多加密的算法,这里介绍一下hashlib的简单使用事例,用hashlib的md5算法加密数据import ha ...

  3. centos下gitlab的简单安装配置

    一.安装前配置yum源 #wget https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh #s ...

  4. Spring Security – security none, filters none, access permitAll

    1.概述 Spring Security提供了几种将请求模式配置为不安全或允许所有访问的机制.取决于这些机制中的哪一种 - 这可能意味着根本不在该路径上运行安全过滤器链,或者运行过滤器链并允许访问 2 ...

  5. mysql join操作

    join的类型 1.  内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结. 2.  外联结:分为外左联结和外右联结. 案例背景 create table java (name ...

  6. Linux crontab 设置定时任务

    crontab crontab 用于设置系统自动执行的周期性任务 # m h dom mon dow user command 17 * * * * root cd / && run- ...

  7. JavaScriptSerializer类序列化日期时需要注意的问题

    1.让我们来看看使用JavaScriptSerializer类序列化日期会出现什么问题? 1)创建用于序列化的测试类,如下: public class Person { public int ID { ...

  8. cf1028C. Rectangles(前缀和)

    题意 给出$n$个矩形,找出一个点,使得至少在$n$个矩阵内 Sol 呵呵哒,昨天cf半夜场,一道全场切的题,我没做出来..不想找什么理由,不会做就是不会做.. 一个很显然的性质,如果存在一个点 / ...

  9. spring boot图片上传至远程服务器并返回新的图片路径

    界面上传图片时考虑到可能会有用户的图片名称一致,使用UUID来对图片名称进行重新生成. //UUIDUtils public class UUIDUtils { public static Strin ...

  10. mac配置android开发环境(一)

    MAC配置ADB环境变量 android环境搭建完成之后需要配置android环境变量,这对以后的运行调试很有帮助. 下面我将一下mac环境下的配置步骤: 1.在本地目录(home directory ...