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中线程池的常见用法以及 ...
随机推荐
- AtCoder Beginner Contest 053 ABCD题
A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...
- 关于vue的源码调试
一直看源码都是硬生生的看, 其实, 还是感觉调试起来会看的比较舒服. GitHub把vue的源码下载下来 npm install && npm run dev 在example中新建一 ...
- axios delete 请求
axios delete 请求 在传递一个参数的时候,直接把参数放在请求连接后面,用'/' 连接就可以了 this.axios.post(this.APIURL+'/'+ID) //http://ww ...
- PHP知识点总结4
file1.php <?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { stat ...
- Java基础之面向对象
面向对象 1.面向对象思想: (1)概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象,强调具备功能的对象: (2)思想特点: ...
- 基于Servlet+smartUpload的文件上传
文件上传在web应用中是非常常见的,现在我就介绍下基于servlet的文件上传,基于Struts2的文件上传可以看: 页面端代码: <%@ page language="java&qu ...
- 6.html图像标记img
<html> <head> <title>第六课标签</title> <meta charset="utf-8"> &l ...
- APP产品体验
一.前言 1.背景介绍 体验人员:羽珞体验时间:2016.4.12~2016.4.14 2.体验环境 产品名称 产品版本 测试设备 设备系统 易助(ehlep) 1.0 TCL J738M A ...
- arcgis jsapi接口入门系列(3):各种类型的图层添加
这里说的tomcat切片,是指arcgis server切片后,把切片图片文件用tomcat发布(其他任意web服务器发布都行) //添加tomcat切片图层 addTomcatTileLayer: ...
- URAL 1776 Anniversary Firework (概率,区间DP)
坑,一开始以为,分成两半的时候去最大那个就行了, 实际上这样是不对的,因为有可能出现小的一半的时间比大的要长, 因为还和等待次数有关,且转移的时候需要用到次数更小的状态, 所以状态定义为二维,dp[i ...