多线程工具类

package com.sf.itdd.link.common.util;

import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.Logger;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public class CustomThreadPool {
    
    private static final Logger logger = Logger.getLogger(CustomThreadPool.class);
    private final static int DEFAULT_MAX_THEARD = 1;// 默认最大线程池个数
    private final static int DEFAULT_MAX_EXECUTESIZE = 1;// 默认单个线程最大执行数据的个数
    private ExecutorService executorService;

    public CustomThreadPool(int maxTheard) {

        logger.info(String.format("定义线程池最大个数:%s", maxTheard));
        if (maxTheard == 0) {
            maxTheard = DEFAULT_MAX_THEARD;
            logger.info(String.format("因为定义线程池最大个数:0 所以采用默认:" + DEFAULT_MAX_THEARD));
        }
        executorService = Executors.newFixedThreadPool(maxTheard);
    }

    public List<ThreadResultVO> executeObject(List inputs, int maxExecuteSize, Class cls, String methodName, Object... objects) {
        long startTime = System.currentTimeMillis();
            logger.info(String.format("任务单号:%s 最大执行个数:%s 入参数据:%s", startTime, maxExecuteSize, JSON.toJSONString(inputs)));
            logger.info(String.format("调用类:%s 调用方法:%s 额外传参:%s", cls.getName(), methodName, JSON.toJSONString(objects)));
            if (maxExecuteSize == 0) {
                maxExecuteSize = DEFAULT_MAX_EXECUTESIZE;
                logger.info(String.format("因为定义单个线程最大执行个数:0 所以采用默认:" + DEFAULT_MAX_EXECUTESIZE));
            }
            if (inputs == null || inputs.isEmpty()) {
                return Collections.EMPTY_LIST;
        }
        int times = (inputs.size() + maxExecuteSize - 1) / maxExecuteSize;
        CountDownLatch countDownLatch = new CountDownLatch(times);
        List<ThreadResultVO> results = new ArrayList<ThreadResultVO>();
        try {
            for (int threadSize = 0; threadSize < times; threadSize++) {
                if (threadSize == times - 1) {
                    executorService.submit(new InvokeOtherClassMethodCallable(
                            inputs.subList(threadSize * maxExecuteSize, inputs.size()), countDownLatch, cls, methodName, objects));
                } else {                   
                    executorService.submit(new InvokeOtherClassMethodCallable(
                            inputs.subList(threadSize * maxExecuteSize, (threadSize + 1) * maxExecuteSize), countDownLatch, cls, methodName, objects));
                }
            }
            // 等待子线程的结束
           countDownLatch.await();
        } catch (Exception e) {
            logger.error(String.format("任务单号:%s 执行异常:", startTime));
            e.printStackTrace();
        } finally {
            logger.info(String.format("任务单号:%s 已经完成。耗时:%s 毫秒", startTime, System.currentTimeMillis() - startTime));
            return results;
        }
    }

    @Data
    public class ThreadResultVO {
        private boolean success;
        private String result;
        private String exception;
    }

    private class InvokeOtherClassMethodCallable implements Callable<ThreadResultVO> {

        private CountDownLatch countDownLatch;
        private Class callbackClass;
        private String methodName;
        private Object[] objects;

        public InvokeOtherClassMethodCallable(List executeParams, CountDownLatch countDownLatch, Class callbackClass, String methodName, Object... objects) {
            this.countDownLatch = countDownLatch;
            this.callbackClass = callbackClass;
            this.methodName = methodName;
            this.objects = new Object[objects.length + 1];
            int i = 0;
            this.objects[i++] = executeParams;
            for (Object object : objects) {
                this.objects[i++] = object;
            }
        }

        public ThreadResultVO call() {
            ThreadResultVO threadResultVO = new ThreadResultVO();
            try {
                // 模拟业务执行,可反射调用其他类方法
                Method tempMethod = null;
                log.info(Thread.currentThread() + "执行开始。。。。");
                for (Method method : callbackClass.getMethods()) {
                    // 以方法名查找方法
                    if (methodName.equals(method.getName())) {
                        // 以参数个数及类型定位
                        Class[] parameterTypes = method.getParameterTypes();
                        if (parameterTypes.length != objects.length) {
                            continue;
                        }
                        int parameterIndex = 0;
                        for (Object object : objects) {
                            if (object.getClass().isInstance(parameterTypes[parameterIndex++])) {
                                continue;
                            }
                            // 最后一次获取方法
                            if (parameterIndex == parameterTypes.length) {
                                tempMethod = method;
                            }
                        }
                    }
                    if (tempMethod != null) {
                        break;
                    }
                }
                if (tempMethod == null) {
                    throw new RuntimeException(String.format("没有找到反射的方法:%s 参数类型:%s", methodName, JSON.toJSONString(objects)));
                }
                Object tempResult = tempMethod.invoke(callbackClass.newInstance(), objects);
                threadResultVO.setSuccess(true);
                threadResultVO.setResult(String.valueOf(tempResult));
            } catch (Exception e) {
                threadResultVO.setSuccess(false);
                threadResultVO.setException(String.format("异常类型:%s 异常内容:%s", e.getCause().getClass().getName(), e.getCause().getMessage()));
                logger.error("异步执行失败:");
                e.printStackTrace();
            } finally {
                log.info(Thread.currentThread() + "执行结束。。。。");
                // 计数减一
                countDownLatch.countDown();
                return threadResultVO;
            }
        }
    }
}
 

 

调取工具类的方法,工具类已经把传的参数按一定比例划分,只要把list参数传入

 

public void customThread() {
        logger.info("进入线程池方法,建立线程池");
        EntityWrapper ewCase = new EntityWrapper();
//        ewCase.limit(1, 1000);
        List<SdeisCmdbRac> listCase = sdeisCmdbRacManager.selectList(ewCase);
        CustomThreadPool customThreadPool = new CustomThreadPool(threads);
        customThreadPool.executeObject(listCase, figure, TaskCmdbTimingManager.class, "pullCase", cmdbUrl, sdeisCmdbAppliedCaseManager);
    }

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值