接口访问限流器(多线程访问)

多线程访问限流接口: 


  /**
     * 多线程同步代码
     * */
    protected Integer syncXXX(List<String> erps, Date startTime, Date endTime) throws Exception {
        int total = 0;
        if(CollectionUtils.isEmpty(erps)) {
            return total;
        }
        
        //TPS(Transaction Per Second) 每秒钟系统能够处理的交易或事务的数量
        int tps = SystemConfigs.getInt(SysConfigKeys.XXX_TPS);
        int tSize = (int) Math.ceil(tps / 5.0);// 预计一个线程每秒5次请求,计算线程数,向上取整
        int slen = (int) Math.ceil(erps.size() / (tSize + 0.0));//单个线程计算的erp个数,向上取整
        int stps = (int) Math.floor(tps / (tSize + 0.0));     // 预计单个线程的访问频率,向下取整
        
        ExecutorService executorService = Executors.newFixedThreadPool(tSize);//建立ExecutorService线程池
        
        List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();
        int sindex = 0;
        while(sindex < erps.size()) {//将erps分配给每个线程
            int limit = sindex + slen;
            List<String> serps = erps.subList(sindex, limit < erps.size() ? limit : erps.size());//单个线程计算的ERP list
            Future<Integer> future = executorService.submit(new XXXeSyncTask(serps, startTime, endTime, stps));
            futureList.add(future);
            sindex = limit;
        }
        for(Future<Integer> future : futureList) {
            total += future.get();
        }
        
        executorService.shutdown();
        
        return total;
    }
    
    class XXXSyncTask implements Callable<Integer> {
        // erp子级,代码行汇总
        private List<String> erps;
        private Date start;
        private Date end;
        // 允许最大访问频率
        private int tps;
        
        public XXXSyncTask(List<String> erps, Date start, Date end, int tps) {
            this.erps = erps;
            this.start = start;
            this.end = end;
            this.tps = tps;
        }

        @Override
        public Integer call() throws Exception {
            long startMillis = System.currentTimeMillis();
            long duration = 0;
            int count = 0;
            List<XXX> xxxList = new ArrayList<XXX>();
            for (int i = 0; i < erps.size(); i++) {
                String erp = erps.get(i);

                while (start.before(end)) {
                    // 预计耗时(ms)
                    long predict = i * 1000 / tps;
                    if (predict > duration) {
                        // 实际耗时小于预计耗时,sleep
                        long waitting = predict - duration;
                        Thread.sleep(waitting);
                        LOG.debug("代码行同步休眠{}ms. ", waitting);
                    }
                    duration = System.currentTimeMillis() - startMillis;
                    
                    List<XXX> tempList = queryData(erp, start);
                    xxxList.addAll(tempList);
                    if (xxxList.size() > 100) {
                        xxxDao.batch(xxxList, SQL_OPTION.INSERT);
                        count += xxxList.size();
                        xxxList.clear();
                    }
                   
                    start = DateUtils.addDay(start, 1);
                }
            }

            if (!xxxList.isEmpty()) {
                xxxDao.batch(codeColumnList, SQL_OPTION.INSERT);
                count += codeColumnList.size();
                xxxList.clear();
            }
            return count;
        }
        
    }

相关文章:

http://www.oschina.net/translate/java-util-concurrent-future-basics

http://www.cnblogs.com/whgw/archive/2011/09/28/2194760.html

你可能感兴趣的:(接口访问限流器(多线程访问))