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);
}
    
原文地址:https://www.cnblogs.com/miye/p/9870828.html