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);
}