zoukankan      html  css  js  c++  java
  • spring多线程初探

    6月14号  晴  最高温度37   今天很热的一天啊,开发的任务现在正在测试阶段,手头没有什么工作任务,忙里偷闲,丰富一下我的blog。

    前两天有个需求:调用第三方接口,这个接口的响应时间有点长,需要5~7秒的响应,而且只能一条一条报文发送,实时返回结果,同步请求。

    所遇到的问题:需要发送的数据量特别大的时候,响应时间可能需要好几十个小时,这个明显是不能接受的。

    方案:初次遇到这样的问题,没有那么丰富的经验和解决方案,能想到的就是启动多线程来解决这个问题。

    下边贴出我实现的关键代码和步骤,欢迎大家发表看法和提出更好的方案。

    首先是配置文件,我用的是spring的线程池,因为对方接口支持的最大并发数200,所以我设置maxPoolSize的值为200,这个值可以根据实际并发来定

    在加一点  我的数据库最大连接数配的50,需要注意的是如果连接数配的小,执行并发是就会报错提示数据库连接数已超

    <!-- spring多线程 -->
         <bean id="taskExecutor"
            class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
            <!-- 核心线程数 -->
            <property name="corePoolSize" value="100" />
            <!-- 最大线程数 -->
            <property name="maxPoolSize" value="200" />
            <!-- 队列最大长度 >=mainExecutor.maxSize -->
            <property name="queueCapacity" value="2500" />
            <!-- 线程池维护线程所允许的空闲时间 -->
            <property name="keepAliveSeconds" value="300" />
            <!-- 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.  -->
            <property name="rejectedExecutionHandler">
                <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
            </property>
        </bean>

    配置文件就上边一个,下边就是实现类MultiThread  需要实现Runnable接口

    public class MultiThread implements Runnable {

        private static final Logger     logger  = LoggerFactory.getLogger(MultiThread.class);

        private IFlowPrizeService       flowPrizeService;//调用其它业务层逻辑需要这么引用

        private List<Map<String,Object> listnew;

        private int                     starNum = 0;                                         //分页  起始数
        private JSONObject              json    = null;

        public MultiThread() {
        }

        public MultiThread(IFlowPrizeService flowPrizeService, List<Map<String,Object> listnew) {
            this.flowPrizeService = flowPrizeService;
            this.listnew= listnew;
        }

        @Override
        public void run() {//执行方法
            threadPrize(flowPrizeService,listnew);//具体实现
        }

    }

    调用

    int starNum = 0;
    for (int i = 0; i <= listnew.size() / 10000; i++) {//listnew需要处理的总数据量   10000是每个线程处理的最大数据量
                 taskExecutor.execute(new MultiThreadNew(iFlowPrizeService,getList(listnew, 10000, starNum)));//getList是按每10000切分listnew 
                 starNum += Integer.valueOf(flowPrizeThread);
    }

    私有方法 对总记录listnew切分

    private List<Map<String,Object> getList(List<Map<String,Object> listnew,
                                                   int flowPrizeThread, int starNum) {
            int end = starNum + flowPrizeThread;
            if (end >= listnew.size()) {
                end = listnew.size();
            }
            return listnew.subList(starNum, end);//subList用法

           /**  List接口有一个实例方法List<E> subList(int fromIndex, int toIndex),其作用是返回一个以fromIndex为起始索引(包含),以toIndex为终止索引(不包含)的子列表(List)。
        但值得注意的是,返回的这个子列表的幕后其实还是原列表;也就是说,修改这个子列表,将导致原列表也发生改变;反之亦然。 **/
        }

  • 相关阅读:
    wpf随笔
    XGrid绑定(转)
    SQL Server 批量插入数据的两种方法(转)
    UdpClient的Connect究竟做了什么(转)
    InvokeHelper,让跨线程访问/修改主界面控件不再麻烦(转)
    [C#] Control.Invoke方法和跨线程访问控件
    多线程访问winform控件出现异常的解决方法
    http://www.jdon.com/mda/oo_relation.html
    三范式浅析(转)
    SQL 表锁(转)
  • 原文地址:https://www.cnblogs.com/boboxing/p/7008370.html
Copyright © 2011-2022 走看看