针对批处理异步任务,可以自定义线程池来处理。
@Component
public class BusinessContext {
/**
* 有请求时,创建线程执行任务,
* 当线程数量等于corePoolSize时,请求加入阻塞队列里,
* 当队列满了时,接着创建线程,线程数等于maximumPoolSize。
* 当任务处理不过来的时候,线程池开始执行拒绝策略。
*/
/**
* 阻塞队列:
*
* ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
*
* LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
*
* PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
*
* DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
*
* SynchronousQueue: 一个不存储元素的阻塞队列。
*
* LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
*
* LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。
*/
/**
* ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
*
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
*
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务。(重复此过程)
*
* ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务。
*/
private ThreadPoolExecutor executor;
private final int CORE_POOL_SIZE = 2;
private final int MAXIMUM_POOL_SIZE = 2;
private final long KEEP_ALIVE_TIME = 20;
@PostConstruct
public void init(){
executor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
new BusinessThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
}
public void run(Runnable runnable){
executor.execute(runnable);
}
public static class BusinessThreadFactory implements ThreadFactory{
private final AtomicInteger atomicInteger = new AtomicInteger(1);
private final ThreadGroup threadGroup;
BusinessThreadFactory(){
SecurityManager s = System.getSecurityManager();
threadGroup = Objects.nonNull(s) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(threadGroup,r,"guoyh-thread-"+atomicInteger.getAndIncrement());
t.setDaemon(false);
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
核心线程数2,最大线程数2,阻塞队列长度3,并发10时,猜测结果: 前5条顺利输出,后5条直接走拒绝策略,抛出RejectedExecutingException
验证代码:
@Resource
private BusinessContext businessContext;
@Test
public void test(){
for (int i = 1; i <= 20; i++) {
final int num = i;
try {
businessContext.run(() -> {
log.info("----{}-start",num);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("----{}-end",num);
});
} catch (RejectedExecutionException e) {
log.error("{}拒绝执行",num);
}
}
while (true){
}
}
运行结果: