RejectedProxyUtil RejectedProxyInvocationHandler
spring容器加载的时候直接进行生成(后续考虑添加外部添加的方式进行)
Bean的生命周期
thread-point中AbstractDynamicExecutorSupport通过继承InitializingBean 和 DisposableBean
将初始化线程池交给子类实现
控制Bean的关闭,实现了是否等待线程完成后销毁
package com.moer.executor.proxy;
import lombok.AllArgsConstructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicLong;
/**
* 拒绝策略代理
*/
@AllArgsConstructor
public class RejectedProxyInvocationHandler implements InvocationHandler {
private final Object target;
private final String threadPoolId;
private final AtomicLong rejectCount;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
rejectCount.incrementAndGet();
try {
return method.invoke(target, args);
} catch (InvocationTargetException ex) {
throw ex.getCause();
}
}
}
package com.moer.executor.proxy;
import java.lang.reflect.Proxy;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.atomic.AtomicLong;
/**
* 拒绝策略代理工具
*/
public class RejectedProxyUtil {
/**
* Proxy rejected execution.
*
* @param rejectedExecutionHandler
* @param threadPoolId
* @param rejectedNum
* @return
*/
public static RejectedExecutionHandler createProxy(RejectedExecutionHandler rejectedExecutionHandler, String threadPoolId, AtomicLong rejectedNum) {
RejectedExecutionHandler rejectedProxy = (RejectedExecutionHandler) Proxy
.newProxyInstance(
rejectedExecutionHandler.getClass().getClassLoader(),
new Class[]{RejectedExecutionHandler.class},
new RejectedProxyInvocationHandler(rejectedExecutionHandler, threadPoolId, rejectedNum));
return rejectedProxy;
}
}
package com.moer.executor.support;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import java.util.concurrent.*;
/**
* @author yrx
* @description: 线程池基类
* @date 2023/8/28 11:39
*/
public abstract class AbstractDynamicExecutorSupport extends ThreadPoolExecutor implements InitializingBean, DisposableBean {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractDynamicExecutorSupport.class);
private String threadPoolId;
private ExecutorService executor;
public long awaitTerminationMillis;
public boolean waitForTasksToCompleteOnShutdown;
public AbstractDynamicExecutorSupport(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
boolean waitForTasksToCompleteOnShutdown,
long awaitTerminationMillis,
BlockingQueue<Runnable> workQueue,
String threadPoolId,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
this.threadPoolId = threadPoolId;
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
this.awaitTerminationMillis = awaitTerminationMillis;
}
protected abstract ExecutorService initializeExecutor();
@Override
public void afterPropertiesSet() {
initialize();
}
@Override
public void destroy() {
shutdownSupport();
}
public void initialize() {
log.info("初始化线程池" + (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : ""));
this.executor = initializeExecutor();
}
public void setSupportParam(long awaitTerminationMillis, boolean waitForTasksToCompleteOnShutdown) {
this.awaitTerminationMillis = awaitTerminationMillis;
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
}
public void shutdownSupport() {
log.info("关闭线程池" + (this.threadPoolId != null ? " '" + this.threadPoolId + "'" : ""));
if (this.executor != null) {
if (this.waitForTasksToCompleteOnShutdown) {
this.executor.shutdown();
} else {
for (Runnable remainingTask : this.executor.shutdownNow()) {
cancelRemainingTask(remainingTask);
}
}
awaitTerminationIfNecessary(this.executor);
}
}
/**
* 取消任务
* @param task
*/
protected void cancelRemainingTask(Runnable task) {
if (task instanceof Future) {
((Future<?>) task).cancel(true);
}
}
/**
* 关闭线程池
* @param executor
*/
private void awaitTerminationIfNecessary(ExecutorService executor) {
if (this.awaitTerminationMillis > 0) {
try {
if (!executor.awaitTermination(this.awaitTerminationMillis, TimeUnit.MILLISECONDS)) {
log.warn("到达指定时间,还有线程没执行完,不再等待" +
(this.threadPoolId != null ? " '" + this.threadPoolId + "'" : "" + ",关闭线程池"));
}
} catch (InterruptedException ex) {
log.warn("打断线程异常" +
(this.threadPoolId != null ? " '" + this.threadPoolId + "'" : ""));
Thread.currentThread().interrupt();
}
}
}
}
package com.moer.executor.support;
import com.moer.executor.DynamicThreadPoolExecutor;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.task.TaskDecorator;
import org.springframework.util.Assert;
import java.util.concurrent.*;
@Slf4j
public class AbstractBuildThreadPoolTemplate {
/**
* 线程池构建初始化参数.
*
* 此处本身是模版设计方法, 但是考虑创建简洁性, 移除 abstract.
*
* @return
*/
protected static ThreadPoolInitParam initParam() {
throw new UnsupportedOperationException();
}
/**
* 创建监听线程池
* @param initParam
* @return
*/
public static DynamicThreadPoolExecutor buildDynamicPool(ThreadPoolInitParam initParam) {
DynamicThreadPoolExecutor dynamicThreadPoolExecutor;
try {
dynamicThreadPoolExecutor = new DynamicThreadPoolExecutor(
initParam.getCorePoolNum(),
initParam.getMaxPoolNum(),
initParam.getKeepAliveTime(),
initParam.getTimeUnit(),
initParam.getExecuteTimeOut(),
initParam.getWaitForTasksToCompleteOnShutdown(),
initParam.getAwaitTerminationMillis(),
initParam.getWorkQueue(),
initParam.getThreadPoolId(),
initParam.getThreadFactory(),
initParam.getRejectedExecutionHandler());
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(String.format("Error creating thread pool parameter. threadPool id :: %s", initParam.getThreadPoolId()), ex);
}
dynamicThreadPoolExecutor.setTaskDecorator(initParam.getTaskDecorator());
dynamicThreadPoolExecutor.allowCoreThreadTimeOut(initParam.allowCoreThreadTimeOut);
return dynamicThreadPoolExecutor;
}
@Data
@Accessors(chain = true)
public static class ThreadPoolInitParam {
private Integer corePoolNum;
private Integer maxPoolNum;
private Long keepAliveTime;
private TimeUnit timeUnit;
private Long executeTimeOut;
private Integer capacity;
private BlockingQueue<Runnable> workQueue;
private RejectedExecutionHandler rejectedExecutionHandler;
private ThreadFactory threadFactory;
private String threadPoolId;
private TaskDecorator taskDecorator;
private Long awaitTerminationMillis;
private Boolean waitForTasksToCompleteOnShutdown;
private Boolean allowCoreThreadTimeOut = false;
}
}
package com.moer.executor.support;
import javafx.util.Builder;
import org.springframework.core.task.TaskDecorator;
import java.math.BigDecimal;
import java.util.Optional;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author yrx
* @description: 线程池构建器
* @date 2023/8/28 13:30
*/
public class ThreadPoolBuilder implements Builder<ThreadPoolExecutor> {
private int corePoolSize = calculateCoreNum();
// 最大线程数为核心线程数的1.5倍
private int maxPoolSize = corePoolSize + (corePoolSize >> 1);
private long keepAliveTime = 30000L;
private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
private int capacity = 512;
private long executeTimeOut = 10000L;
private BlockingQueue workQueue = new LinkedBlockingQueue(capacity);
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
private TaskDecorator taskDecorator;
private String threadPoolId;
private Boolean waitForTasksToCompleteOnShutdown = true;
private Long awaitTerminationMillis = 5000L;
private Boolean allowCoreThreadTimeOut = false;
private ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger index = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
String threadName = "任务处理线程[HandleTaskExecutor]-" + (null != r ? r.getClass().getSimpleName() : "") + "#" + index.getAndIncrement();
return new Thread(r, threadName);
}
};
/**
* 5倍cpu核心数
* @return
*/
private Integer calculateCoreNum() {
int cpuCoreNum = Runtime.getRuntime().availableProcessors();
return new BigDecimal(cpuCoreNum).divide(new BigDecimal("0.2")).intValue();
}
public ThreadPoolBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) {
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
return this;
}
public ThreadPoolBuilder threadPoolId(String threadPoolId) {
this.threadPoolId = threadPoolId;
return this;
}
public ThreadPoolBuilder workQueue(BlockingQueue workQueue) {
this.workQueue = workQueue;
return this;
}
public ThreadPoolBuilder executeTimeOut(long executeTimeOut) {
this.executeTimeOut = executeTimeOut;
return this;
}
public ThreadPoolBuilder keepAliveTime(long keepAliveTime) {
this.keepAliveTime = keepAliveTime;
return this;
}
public ThreadPoolBuilder awaitTerminationMillis(long awaitTerminationMillis) {
this.awaitTerminationMillis = awaitTerminationMillis;
return this;
}
public ThreadPoolBuilder waitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown) {
this.waitForTasksToCompleteOnShutdown = waitForTasksToCompleteOnShutdown;
return this;
}
public ThreadPoolBuilder keepAliveTime(long keepAliveTime, TimeUnit timeUnit) {
this.keepAliveTime = keepAliveTime;
this.timeUnit = timeUnit;
return this;
}
public ThreadPoolBuilder capacity(int capacity) {
this.capacity = capacity;
return this;
}
public ThreadPoolBuilder rejected(RejectedExecutionHandler rejectedExecutionHandler) {
this.rejectedExecutionHandler = rejectedExecutionHandler;
return this;
}
public ThreadPoolBuilder taskDecorator(TaskDecorator taskDecorator) {
this.taskDecorator = taskDecorator;
return this;
}
public ThreadPoolBuilder corePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
return this;
}
public ThreadPoolBuilder maxPoolNum(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
return this;
}
public ThreadPoolBuilder threadFactory(ThreadFactory threadFactory){
this.threadFactory = threadFactory;
return this;
}
public static ThreadPoolBuilder builder() {
return new ThreadPoolBuilder();
}
@Override
public ThreadPoolExecutor build() {
return buildDynamicPool(this);
}
private static ThreadPoolExecutor buildDynamicPool(ThreadPoolBuilder builder) {
return AbstractBuildThreadPoolTemplate.buildDynamicPool(buildInitParam(builder));
}
private static AbstractBuildThreadPoolTemplate.ThreadPoolInitParam buildInitParam(ThreadPoolBuilder builder) {
AbstractBuildThreadPoolTemplate.ThreadPoolInitParam initParam =
new AbstractBuildThreadPoolTemplate.ThreadPoolInitParam();
initParam.setCorePoolNum(builder.corePoolSize)
.setMaxPoolNum(builder.maxPoolSize)
.setKeepAliveTime(builder.keepAliveTime)
.setCapacity(builder.capacity)
.setExecuteTimeOut(builder.executeTimeOut)
.setRejectedExecutionHandler(builder.rejectedExecutionHandler)
.setTimeUnit(builder.timeUnit)
.setThreadFactory(builder.threadFactory)
.setAllowCoreThreadTimeOut(builder.allowCoreThreadTimeOut)
.setTaskDecorator(builder.taskDecorator);
initParam.setThreadPoolId(builder.threadPoolId);
initParam.setWaitForTasksToCompleteOnShutdown(builder.waitForTasksToCompleteOnShutdown);
initParam.setAwaitTerminationMillis(builder.awaitTerminationMillis);
initParam.setWorkQueue(builder.workQueue);
return initParam;
}
}
package com.moer.executor.toolkit;
import java.lang.reflect.Array;
public class ArrayUtil {
/**
* Is empty.
*
* @param array
* @param
* @return
*/
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length == 0;
}
/**
* Is not empty.
*
* @param array
* @param
* @return
*/
public static <T> boolean isNotEmpty(T[] array) {
return !isEmpty(array);
}
/**
* Add all.
*
* @param array1
* @param array2
* @param
* @return
*/
public static <T> T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
}
final Class<?> type1 = array1.getClass().getComponentType();
@SuppressWarnings("unchecked")
final T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
try {
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
} catch (final ArrayStoreException ase) {
final Class<?> type2 = array2.getClass().getComponentType();
if (!type1.isAssignableFrom(type2)) {
throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of "
+ type1.getName(), ase);
}
throw ase;
}
return joinedArray;
}
/**
* Clone.
*
* @param array
* @param
* @return
*/
public static <T> T[] clone(final T[] array) {
if (array == null) {
return null;
}
return array.clone();
}
}
package com.moer.executor.toolkit;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* 系统时间工具
*/
public class SystemClock {
private final int period;
private final AtomicLong now;
private static final String THREAD_NAME = "system.clock";
private static class InstanceHolder {
private static final SystemClock INSTANCE = new SystemClock(1);
}
private SystemClock(int period) {
this.period = period;
this.now = new AtomicLong(System.currentTimeMillis());
scheduleClockUpdating();
}
private static SystemClock instance() {
return InstanceHolder.INSTANCE;
}
private void scheduleClockUpdating() {
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1, r -> {
Thread thread = new Thread(r, THREAD_NAME);
thread.setDaemon(true);
return thread;
});
scheduler.scheduleAtFixedRate(() -> now.set(System.currentTimeMillis()), period, period, TimeUnit.MILLISECONDS);
}
private long currentTimeMillis() {
return now.get();
}
public static long now() {
return instance().currentTimeMillis();
}
}
package com.moer.executor;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 普通异步处理任务基类
* 马上排队执行
*
*/
public abstract class AbstractAsyncHandleTask<P> extends AbstractHandleTask {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAsyncHandleTask.class);
/**
* 对象形式的入参
*/
protected P param;
/**
* 任务构造方法
*
* @param param 请求参数
*/
public AbstractAsyncHandleTask(P param) {
this.param = param;
}
/**
* 一个普通异步任务的业务处理
*
* @param param 业务数据
* @return
* @throws Exception
*/
public abstract boolean handle(P param) throws Exception;
/**
* 任务运行
*
* @see Runnable#run()
*/
@Override
public void run() {
try {
LOGGER.debug(">>> 一个普通异步任务的开始执行,入参:{}", param);
if (null != param && param instanceof String ? StrUtil.isNotBlank(String.valueOf(param)) : true) {
handle(this.param);
} else {
LOGGER.warn(">>> 一个普通异步任务被忽略了,因入参为null");
}
} catch (Throwable e) {
LOGGER.error("普通异步任务执行异常", e);
} finally {
}
}
@Override
public String rejected() {
return Convert.toStr(param);
}
}
package com.moer.executor;
import java.util.concurrent.Callable;
/**
* 处理任务基类
*
*/
public abstract class AbstractCallBackHandleTask implements Callable<Object> {
}
package com.moer.executor;
/**
* 处理任务基类
*/
public abstract class AbstractHandleTask implements Runnable {
/**
* 任务被线程池拒绝时的日志信息
*
* @return 日志信息
*/
public abstract String rejected();
}
package com.moer.executor;
import com.moer.executor.proxy.RejectedProxyUtil;
import com.moer.executor.support.AbstractDynamicExecutorSupport;
import com.moer.executor.toolkit.SystemClock;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.springframework.core.task.TaskDecorator;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
public class DynamicThreadPoolExecutor extends AbstractDynamicExecutorSupport {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DynamicThreadPoolExecutor.class);
@Getter
@Setter
private Long executeTimeOut;
@Getter
@Setter
private TaskDecorator taskDecorator;
@Getter
@Setter
private RejectedExecutionHandler redundancyHandler;
@Getter
private final String threadPoolId;
@Getter
private final AtomicLong rejectCount = new AtomicLong();
private final ThreadLocal<Long> startTime = new ThreadLocal<>();
public DynamicThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
long executeTimeOut,
boolean waitForTasksToCompleteOnShutdown,
long awaitTerminationMillis,
@NonNull BlockingQueue<Runnable> workQueue,
@NonNull String threadPoolId,
@NonNull ThreadFactory threadFactory,
@NonNull RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, waitForTasksToCompleteOnShutdown, awaitTerminationMillis, workQueue, threadPoolId, threadFactory, handler);
this.threadPoolId = threadPoolId;
this.executeTimeOut = executeTimeOut;
RejectedExecutionHandler rejectedProxy = RejectedProxyUtil.createProxy(RejectedPolicyTypeEnum.createPolicy(12), threadPoolId, rejectCount);
setRejectedExecutionHandler(rejectedProxy);
redundancyHandler = handler;
}
@Override
public void execute(@NonNull Runnable command) {
if (taskDecorator != null) {
// 可以针对命令以及参数进行装饰
command = taskDecorator.decorate(command);
}
super.execute(command);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
if (executeTimeOut == null || executeTimeOut <= 0) {
return;
}
this.startTime.set(SystemClock.now());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (executeTimeOut == null || executeTimeOut <= 0) {
return;
}
try {
long startTime = this.startTime.get();
long endTime = SystemClock.now();
long executeTime;
boolean executeTimeAlarm = (executeTime = (endTime - startTime)) > executeTimeOut;
if (executeTimeAlarm ) {
// 异步执行提醒
log.info(threadPoolId + "执行时间:"+ executeTime + ",执行超时时间:"+ executeTimeOut);
}
} finally {
this.startTime.remove();
}
}
@Override
protected ExecutorService initializeExecutor() {
return this;
}
public Long getRejectCountNum() {
return rejectCount.get();
}
}
package com.moer.executor;
import com.moer.executor.support.ThreadPoolBuilder;
import org.springframework.core.task.TaskDecorator;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.util.Assert;
import cn.hutool.core.thread.ThreadUtil;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 通用线程池任务处理执行器
*/
public class HandleTaskExecutor {
private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(HandleTaskExecutor.class);
private static String threadPoolId = "myThread";
/**
* 核心线程大小
*/
private static int CORE_POOL_SIZE = 1;
/**
* 线程池最大线程数
*/
private static int MAX_POOL_SIZE = 1;
/**
* 额外线程空状态生存时间
*/
private static int KEEP_ALIVE_TIME = 30 * 1000;
/**
* 队列大小
*/
private static int MAX_QUEUE_SIZE = 1;
private HandleTaskExecutor() {
}
private static class TmcHandleTaskExecutorHolder {
static HandleTaskExecutor me = new HandleTaskExecutor();
}
/**
* 拿到执行器实例
*
* @return
*/
public static HandleTaskExecutor me() {
return TmcHandleTaskExecutorHolder.me;
}
private static ThreadPoolExecutor THREAD_POOL = ThreadPoolBuilder.builder()
.threadPoolId(threadPoolId)
.executeTimeOut(900L)
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationMillis(5000L)
.corePoolSize(CORE_POOL_SIZE)
.maxPoolNum(MAX_POOL_SIZE)
.keepAliveTime(KEEP_ALIVE_TIME)
.capacity(MAX_QUEUE_SIZE)
.workQueue(new LinkedBlockingQueue<Runnable>(1))
.taskDecorator(new TaskDecorator() {
@Override
public Runnable decorate(Runnable runnable) {
LOGGER.info("装饰线程");
ThreadUtil.sleep(500);
return ()->{
runnable.run();
};
}
})
.rejected(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 线程池过载 抛出异常
String info = "";
if (r instanceof AbstractHandleTask) {
AbstractHandleTask task = (AbstractHandleTask) r;
info = task.rejected();
}
throw new TaskRejectedException(String.format("线程池过载,任务被拒绝。%s", info));
}
})
.build();
/**
* 添加任务
*/
public void execute(AbstractHandleTask handleTask) throws Exception {
LOGGER.debug("THREAD_POOL:{},\n handleTask:{}", THREAD_POOL, handleTask);
THREAD_POOL.execute(handleTask);
}
/**
* 添加任务(捕捉异常)
*/
public void executeCatchException(AbstractHandleTask handleTask) {
try {
LOGGER.debug("THREAD_POOL:{},\n handleTask:{}", THREAD_POOL, handleTask);
THREAD_POOL.execute(handleTask);
} catch (Exception ex) {
LOGGER.error("添加任务异常", ex);
}
}
/**
* 添加任务,批量返回
*/
public List<Future<?>> execute(List<AbstractCallBackHandleTask> handleTasks) throws Exception {
Assert.notEmpty(handleTasks, "任务不能为空");
List<Future<?>> list = new CopyOnWriteArrayList<>();
for (AbstractCallBackHandleTask task : handleTasks) {
Future<?> future = THREAD_POOL.submit(task);
list.add(future);
}
return list;
}
}
package com.moer.executor;
import com.moer.executor.example.ExampleHandleTask;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
/**
* @author yrx
* @description: TODO
* @date 2023/8/28 14:57
*/
@SpringBootApplication
public class executorApplication {
public static void main(String[] args) {
new SpringApplication(executorApplication.class).run(args);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
try {
HandleTaskExecutor.me().execute(new ExampleHandleTask(i+""));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
try {
HandleTaskExecutor.me().execute(new ExampleHandleTask(i+""));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
try {
HandleTaskExecutor.me().execute(new ExampleHandleTask(i+""));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}).start();
}
}
拒绝策略枚举
public enum RejectedPolicyTypeEnum {
CALLER_RUNS_POLICY(1, "CallerRunsPolicy", new ThreadPoolExecutor.CallerRunsPolicy()),
ABORT_POLICY(2, "AbortPolicy", new ThreadPoolExecutor.AbortPolicy()),
DISCARD_POLICY(3, "DiscardPolicy", new ThreadPoolExecutor.DiscardPolicy()),
DISCARD_OLDEST_POLICY(4, "DiscardOldestPolicy", new ThreadPoolExecutor.DiscardOldestPolicy());
@Getter
private Integer type;
@Getter
private String name;
private RejectedExecutionHandler rejectedHandler;
RejectedPolicyTypeEnum(Integer type, String name, RejectedExecutionHandler rejectedHandler) {
this.type = type;
this.name = name;
this.rejectedHandler = rejectedHandler;
}
@Component
private static class InitializeErrorCodeConfig {
@PostConstruct
private void init() {
ServiceLoaderRegistry.register(CustomRejectedExecutionHandler.class);
}
}
public static RejectedExecutionHandler createPolicy(String name) {
RejectedPolicyTypeEnum rejectedTypeEnum = Stream.of(RejectedPolicyTypeEnum.values())
.filter(each -> Objects.equals(each.name, name))
.findFirst()
.orElse(null);
if (rejectedTypeEnum != null) {
return rejectedTypeEnum.rejectedHandler;
}
Collection<CustomRejectedExecutionHandler> customRejectedExecutionHandlers = ServiceLoaderRegistry
.getSingletonServiceInstances(CustomRejectedExecutionHandler.class);
Optional<RejectedExecutionHandler> customRejected = customRejectedExecutionHandlers.stream()
.filter(each -> Objects.equals(name, each.getName()))
.map(each -> each.generateRejected())
.findFirst();
return customRejected.orElse(ABORT_POLICY.rejectedHandler);
}
public static RejectedExecutionHandler createPolicy(int type) {
Optional<RejectedExecutionHandler> rejectedTypeEnum = Stream.of(RejectedPolicyTypeEnum.values())
.filter(each -> Objects.equals(type, each.type))
.map(each -> each.rejectedHandler)
.findFirst();
RejectedExecutionHandler resultRejected = rejectedTypeEnum.orElseGet(() -> {
Collection<CustomRejectedExecutionHandler> customRejectedExecutionHandlers = ServiceLoaderRegistry
.getSingletonServiceInstances(CustomRejectedExecutionHandler.class);
Optional<RejectedExecutionHandler> customRejected = customRejectedExecutionHandlers.stream()
.filter(each -> Objects.equals(type, each.getType()))
.map(each -> each.generateRejected())
.findFirst();
return customRejected.orElse(ABORT_POLICY.rejectedHandler);
});
return resultRejected;
}
public static String getRejectedNameByType(int type) {
return createPolicy(type).getClass().getSimpleName();
}
public static RejectedPolicyTypeEnum getRejectedPolicyTypeEnumByName(String name) {
Optional<RejectedPolicyTypeEnum> rejectedTypeEnum = Stream.of(RejectedPolicyTypeEnum.values())
.filter(each -> each.name.equals(name))
.findFirst();
return rejectedTypeEnum.orElse(ABORT_POLICY);
}
}
缓存
public class ServiceLoaderRegistry {
private static final Map<Class<?>, Collection<?>> SERVICES = new ConcurrentHashMap<>();
private ServiceLoaderRegistry() {
}
/**
* Register.
*
* @param serviceInterface
*/
public static void register(final Class<?> serviceInterface) {
if (!SERVICES.containsKey(serviceInterface)) {
SERVICES.put(serviceInterface, load(serviceInterface));
}
}
/**
* Load.
*
* @param serviceInterface
* @param
* @return
*/
private static <T> Collection<T> load(final Class<T> serviceInterface) {
Collection<T> result = new LinkedList<>();
ServiceLoader<T> tServiceLoader = ServiceLoader.load(serviceInterface);
for (T each : tServiceLoader) {
result.add(each);
}
return result;
}
@SuppressWarnings("unchecked")
public static <T> Collection<T> getSingletonServiceInstances(final Class<T> service) {
return (Collection<T>) SERVICES.getOrDefault(service, Collections.emptyList());
}
}