集群多线程设计

为了加快执行速度,使得设计集群内机器开启多线程执行,执行数据。

1)   发起服务的机器称为主服务器,首先主服务器获取需要处理数据的最大最小ID,以及获取需要参与处理的集群节点服务器IP

2)   将该批数据均匀分布给参与处理的机器节点,每台机器获取到需要处理的该批次数据段最大最小ID

3)   使用Redis消息机制,发布消息,集群下机器订阅到消息,而获取到消息的机器判断自己是否需要参与处理

4)   需要参与处理的机器获取需要处理的数据量,以及每个线程处理数据大小和开启线程大小,分页获取该次要处理的数据

5)   将分页获取该次要处理的数据等参数传输给多线程程序,从线程池内取出线程开启多线程进行处理

6)   节点机器获取线程处理结果,通过消息发送出去,主服务器订阅处理结果,当主服务器获取所有节点结果,将结果反馈出去,执行完成;

 

 

    /**

     * 按服务器平分集合

     * @param oneSize 每次数据量

     * @param list 总的list

     * @return

     */

    public Map<Integer,List<T>> splitList(Integer oneSize, List<T> list){

        Map<Integer,List<T>> map = new HashMap<>();

        //数量小于线程数

        if(oneSize>=list.size()){

            map.put(0,list);

            return map;

        }

        int totalSize = list.size(); //总数据量

        int one = totalSize%oneSize==0?0:1;

        int poolSize = totalSize / oneSize+one;  //总线程数

        for (int i = 0; i < poolSize; i++) {

            int sizeEnd = (i+1)*oneSize;

            if(sizeEnd>totalSize){

                sizeEnd=totalSize;

            }

            List<T> value = list.subList(i * oneSize, sizeEnd);

            map.put(i,value);

        }

        return map;

    }

 

 

 

开启多线程核心代码:

    public List<Map<String,Object>> executeCallable(Integer poolSize,Integer number, List<T> listData, String code) {

        // 等待线程返回所有结果

        List<Map<String,Object>> finalist = new ArrayList<>();

        int totalSize = listData.size(); //总数据量

        int sizeOne =poolSize*number; //一次传输的数据量

        int one = totalSize%sizeOne==0?0:1;

        int sizeFor = totalSize/sizeOne+one; //需要调用循环次数

        for(int j=0;j<sizeFor;j++){

            int sizeEnd = (j+1)*sizeOne;

            if(sizeEnd>=totalSize){

                sizeEnd=totalSize;

            }

            List<T> datas = listData.subList(j*sizeOne,sizeEnd);

            List<Future<Map<String,Object>>> futureList = new ArrayList<>();

            Map<Integer,List<T>> map = splitList(number,datas);

            // 根据map大小开启对应的线程数量

            for (int i=0;i<map.size();i++) {

                // 开启线程

                final int finalI = i;

                List<T> list = map.get(finalI);

                Callable<Map<String,Object>> task = new Callable() {

                    @Override

                    public Map<String,Object> call() throws Exception {

                        logger.info("线程"+finalI+"的集合大小:"+map.get(finalI).size());

                        // 业务逻辑代码

                        switch (code){

                            case "XXX":{ //XXX

                                return

                            }

                        }

                        return null;

                    }

                };

 

                Future<Map<String,Object>> future = threadPoolTaskExecutor.submit(task);  //任务提交到线程池并启动

                futureList.add(future);

            }

            for(Future<Map<String,Object>> future:futureList)

            {

                Map<String,Object> mapOne=null;

                try {

                    mapOne = future.get();   // 等待future对应的线程执行结束

                } catch(Exception e) {

                    logger.error(e.getMessage());

                    mapOne = new HashedMap();

                    mapOne.put(RETURN_CODE,"E");

                    mapOne.put(RETURN_MESSAGE,e.getMessage());

                    e.printStackTrace();

                }finally {

                    finalist.add(mapOne);

                }

            }

            logger.info("最终集合大小:" + finalist.size());

        }

        return finalist;

    }

posted @ 2019-07-06 16:31  爱上胡萝卜的猴子  阅读(685)  评论(0编辑  收藏  举报