线程池工具类?
不是谁都会用,要什么工具类,就算要、又能怎么样。ok
先看使用,简单些
// 正常
ThreadPoolExecutor threadPoolExecutor = SpringUtils.getBean("BfThreadPool");
threadPoolExecutor.execute(() -> { // 业务代码 });
// 我的
new BfThreadPoolUtils<>().setName(" 请求数据")
.addConsumers(integer -> { // 业务代码 }, "数据进行入库")
.addConsumers(integer -> { // 业务代码 }, "数据进行入库")
.addConsumers(integer -> { // 业务代码 }, "数据进行入库")
.Run();
这里觉得没什么,都一样嘛,比如复杂些:主线程等等子线程
//正常
ThreadPoolExecutor threadPoolExecutor = SpringUtils.getBean("BfThreadPool");
CountDownLatch latch = new CountDownLatch(3);
threadPoolExecutor.execute(() -> {
// 业务代码
try {
integerConsumer.accept(finalI);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
threadPoolExecutor.execute(() -> {
// 业务代码
try {
integerConsumer.accept(finalI);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
threadPoolExecutor.execute(() -> {
// 业务代码
try {
integerConsumer.accept(finalI);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
try {
// 主线程等待所有任务完成
latch.await(120l,TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
log.info(explain + "完成!");
我的
new BfThreadPoolUtils<>().setName(" 请求数据")
.addConsumers(integer -> {
// 业务代码
}, "数据进行入库")
.addConsumers(integer -> {
// 业务代码
}, "数据进行入库")
.addConsumers(integer -> {
// 业务代码
}, "数据进行入库")
// 主线程等等子线程
.openMainThreadAwait(data -> {
// 子线程中有出现异常操作
}, errorData -> {
// 主线程等等异常操作
}, "未达到指定的请求数之前出现异常").Run();
log.info(explain + "完成!");
主要是每次都要写try-catch等等一长串的代码,有必要嘛,咳,正常写还是有必要的,但我们可以简化些。
下面是这个工具类
/**
* 线程池工具类
*/
@Slf4j
public class HyThreadPoolUtils<T> {
//返回值不处理子任务(子任务有方法名)
private CopyOnWriteArrayList<Map<String, Function<Integer, T>>> functionsName = new CopyOnWriteArrayList<>();
//返回值处理方法(仅对于有返回值的子任务)
private Function<List<T>, Object> resultFunction;
//无返回值子任务(子任务有方法名)
private CopyOnWriteArrayList<Map<String, Object>> consumersName = new CopyOnWriteArrayList<>();
// 任务名称
private String name;
// 让一个线程在达到指定的请求次数之前等待(默认null)
private CountDownLatch latch;
// 是否存在异常
AtomicReference<Boolean> isError = new AtomicReference<>(false);
// 子线程出现异常,放入传入的参数
private CopyOnWriteArrayList<Object> errorData = new CopyOnWriteArrayList<>();
// 线程池
private ThreadPoolExecutor threadPoolExecutor;
// 有返回值方法的 返回值
private Object object;
// 子线程出现异常处理方法
private Consumer childThreadErrorMethod;
// CountDownLatch等待出现异常处理方法
private Consumer countDownLatchErrorMethod;
// CountDownLatch等待出现异常处理方法,异常信息说明
private String countDownLatchErrorMethodExplain;
// 是否开启主线程等待子线程执行完成
private Boolean ifMainThreadAwait = false;
/**
* 运行方法(必须要执行此方法才能运行)
*
* @return
*/
public HyThreadPoolUtils Run() {
// 总任务个数
int numberSubtasks = functionsName.size() + consumersName.size();
// 执行三种方法
name = getName(this.name);
// 开启主线程等待子线程,则要进行初始化CountDownLatch
if (this.ifMainThreadAwait) {
// 让一个线程在达到指定的请求次数之前等待
this.latch = new CountDownLatch(numberSubtasks);
}
// 获取到线程池
threadPoolExecutor = SpringUtils.getBean("HyThreadPool");
// 执行无返回方法
threadExecution();
// 执行有返回方法
List<T> resultList = threadExecutionResult();
if (resultFunction != null) {
// 处理结果然后返回
object = resultFunction.apply(resultList);
}else {
object = resultList;
}
// 进行主线程等待
if (ifMainThreadAwait) {
try {
// 主线程等待所有任务完成
latch.await(120l,TimeUnit.SECONDS);
// 获取线程执行过程中是否有异常
// 其中一个子线程出现异常,进行对应操作
if (isError.get()) {
// 自定义操作方法
childThreadErrorMethod.accept(errorData);
}
} catch (Exception e) {
// 主线程等待超时,出现异常,事务回滚
log.error(name + " ," + countDownLatchErrorMethodExplain + ", 主线程等待超时,出现异常,异常:" + e.toString());
// 自定义操作方法
countDownLatchErrorMethod.accept(errorData);
e.printStackTrace();
}
}
return this;
}
/**
* 执行无返回方法
*/
public void threadExecution() {
for (int i = 0; i < consumersName.size(); i++) {
int finalI = i;
// 执行方法
threadPoolExecutor.execute(() -> {
String subtaskName = String.valueOf(consumersName.get(finalI).get("name"));
Consumer<Integer> integerConsumer = (Consumer<Integer>) consumersName.get(finalI).get("method");
try {
integerConsumer.accept(finalI);
} catch (Exception e) {
isError.set(true);
errorData.add(consumersName.get(finalI).get("data"));
subtaskName = StrUtil.isEmpty(subtaskName) ? String.valueOf(finalI) : subtaskName;
log.error("-->任务名称:" + name + ":" + ",无返回值,子任务:" + subtaskName + ",执行异常:" + e.toString());
e.printStackTrace();
} finally {
latch.countDown();
}
});
}
}
/**
* 执行有返回方法
*
* @return
*/
public List<T> threadExecutionResult() {
// 返回结果
List<T> resultList = new ArrayList<>();
List<FutureTask<T>> futureTaskList = new ArrayList<>();
for (int i = 0; i < functionsName.size(); i++) {
int finalI = i;
// 执行方法
FutureTask futureTask = new FutureTask<T>(() -> {
T apply = null;
String subtaskName = "";
try {
Function<Integer, T> integerTFunction = functionsName.get(finalI).values().iterator().next();
apply = integerTFunction.apply(finalI);
return apply;
} catch (Exception e) {
this.isError.set(true);
subtaskName = StrUtil.isEmpty(subtaskName) ? String.valueOf(finalI) : subtaskName;
log.error("-->任务名称:" + name + ":" + ",有返回值,不处理子任务:" + subtaskName + ",执行异常:" + e.toString());
e.printStackTrace();
return null;
} finally {
this.latch.countDown();
}
});
futureTaskList.add(futureTask);
threadPoolExecutor.submit(futureTask);
}
// 获取结果
for (FutureTask<T> futureTask : futureTaskList) {
try {
// get方法会阻塞,直到获取结果为止
// futureTask.get();
resultList.add(futureTask.get(60, TimeUnit.SECONDS));
} catch (InterruptedException e) { // 线程被中断将会进入此处
e.printStackTrace();
log.info("-->中断异常");
throw new RuntimeException("系统异常!");
} catch (ExecutionException e) { // 线程执行异常将会进入此处
e.printStackTrace();
log.info("-->执行异常");
throw new RuntimeException("系统异常!");
} catch (TimeoutException e) { // 获取结果超时将会进入此处
e.printStackTrace();
log.info("-->超时异常");
throw new RuntimeException("系统异常!");
}
}
return resultList;
}
/**
* 获取任务名称
*
* @param prefix 任务名称前缀
* @return
*/
public String getName(String prefix) {
String id = String.valueOf(HyIdUtils.getNextId());
return StrUtil.isEmpty(prefix) ? id : prefix + ":" + id;
}
/**
* ‘添加有返回值任务
* @param function
* @param name
* @return
*/
public HyThreadPoolUtils addFunctions(Function<Integer, T> function, String name) {
functionsName.add(new HashMap<String, Function<Integer, T>>() {{
put(name, function);
}});
return this;
}
/**
* 添加无返回值任务
* @param consumer
* @param name
* @return
*/
public HyThreadPoolUtils addConsumers(Consumer<Integer> consumer, String name) {
consumersName.add(new HashMap<String, Object>() {{
put("method", consumer);
put("name", name);
}});
return this;
}
/**
* 添加无返回值任务
* @param consumer
* @param name
* @param data 可以通过getErrorData()方法获取出现异常的子线程中的data数据
* @return
*/
public HyThreadPoolUtils addConsumers(Consumer<Integer> consumer, String name, Object data) {
consumersName.add(new HashMap<String, Object>() {{
put("method", consumer);
put("name", name);
put("data", data);
}});
return this;
}
/**
* 添加有返回值任务,所有任务执行完成后进行处理的方法
* @param resultFunction
* @return
*/
public HyThreadPoolUtils addResultFunctions(Function<List<T>, Object> resultFunction) {
this.resultFunction = resultFunction;
return this;
}
/**
* 设置任务名称
* @param name
* @return
*/
public HyThreadPoolUtils setName(String name) {
this.name = name;
return this;
}
/**
* 获取子线程是否有异常
* @return
*/
public AtomicReference<Boolean> getIsError() {
return isError;
}
/**
* 执行主线程等待子线程
* @param childThreadErrorMethod
* @param countDownLatchErrorMethod
* @param countDownLatchErrorMethodExplain
* @return
*/
public HyThreadPoolUtils openMainThreadAwait(Consumer childThreadErrorMethod, Consumer countDownLatchErrorMethod, String countDownLatchErrorMethodExplain) {
this.ifMainThreadAwait = true;
this.childThreadErrorMethod = childThreadErrorMethod;
this.countDownLatchErrorMethod = countDownLatchErrorMethod;
this.countDownLatchErrorMethodExplain = countDownLatchErrorMethodExplain;
return this;
}
/**
* 获取有参方法返回结果
* @return
*/
public Object getObject() {
return object;
}
/**
* 获取放入线程前的,自定义数据
* @return
*/
public List<Object> getErrorData() {
return this.errorData;
}
最后,仅自己学习记录所用,如有不对,或者错误也欢迎指正,哈哈哈哈
感谢: