首先看看阿里java规范中对线程池使用的规范
不允许使用Executors创建线程池,创建的线程池数量可以为Integer.MAX_VALUE,可能导致OOM
推荐使用
ThreadPoolExecutor创建
看看其4构造方法
看参数最多的一个,上面的都是调这个方法
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
翻译一下
ThreadPoolExecutor(核心线程大小, 最大线程数,线程保持时间,保持时间单位, 缓存队列,线程工厂,拒绝策略)
前四个比较容易理解,看后面几个就好了
缓存队列:任务多的时候,没有多余线程执行任务,这些任务去队列排队,先进先出的原则,这里队列大小是有限制的,队排满了怎么办,用后面的拒绝策略来处理
线程工厂:
继承java.util.concurrent.ThreadFactory,下面是可用的两个工厂
Executors.defaultThreadFactory();
Executors.privilegedThreadFactory();
拒绝策略:队列满了,后面的任务排不进去怎么处理,四种策略
1.AbortPolicy(终止策略)
这是一个处理器针对被拒绝的任务 直接抛出RejectedExecutionException异常(任务无法执行抛出异常)
2.DiscardPolicy(丢弃策略)
什么都不做,也不抛出异常
3.DiscardOldestPolicy(丢弃旧任务策略)
一种被拒绝任务的处理程序,它丢弃(workQueue队列)最老的未被处理请求(队列最先被放进去的任务),然后调用e.execute(r)重试执行当前任务(注意依然要走流程),除非执行器关闭,在这种情况下任务被丢弃。
4.CallerRunsPolicy(调用方运行策略)
被拒绝任务的处理程序,它直接由提交任务的线程来运行这个提交的任务,除非executor已关闭,在这种情况下任务被丢弃。
测试一下
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
@Slf4j
public class Test {
private static BlockingQueue blockingQueue = new ArrayBlockingQueue(5);
private static ExecutorService executorService = new ThreadPoolExecutor(1, 5, 60, TimeUnit.SECONDS, blockingQueue, new ThreadPoolExecutor.AbortPolicy());
/**
* 主线程分配任务,任务被拒绝执行后暂停2秒,之后继续分配任务
*
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i < 31; i++) {
log.debug("第{}个任务", i);
try {
test(i);
} catch (RejectedExecutionException e) {
log.error("拒绝执行{}", i);
Thread.sleep(2000);
log.debug("继续执行{}", i);
test(i);
}
}
}
private static void test(final int index) {
executorService.submit(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error("InterruptedException", e);
}
log.debug("test run {}", index);
});
log.debug("队列剩余空间:{}", blockingQueue.remainingCapacity());
}
}
执行结果
1、核心线程先初始化一个线程
2、第1个任务直接给线程
3、第2-6加入队列,装满了
4、第7-10需创建线程用于执行任务
5、到此队列5个和线程五个一起最多处理10任务,第11个任务拒绝处理,等待中...
6、继续执行,利用释放的线程和队列继续处理(优先使用线程,没有加入队列)...
"F:\Program Files\Java\jdk1.8.0_212\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.1\lib\idea_rt.jar=59703:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\Administrator\AppData\Local\Temp\classpath1401389501.jar org.jeecg.modules.Test
16:35:47.264 [main] DEBUG org.jeecg.modules.Test - 第1个任务
16:35:47.317 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第2个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第3个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第4个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第5个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第6个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第7个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第8个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第9个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第10个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第11个任务
16:35:47.319 [main] ERROR org.jeecg.modules.Test - 拒绝执行11
16:35:48.344 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 1
16:35:48.344 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 7
16:35:48.345 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 8
16:35:48.345 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 9
16:35:48.345 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 10
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 继续执行11
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第12个任务
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第13个任务
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第14个任务
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 第15个任务
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 第16个任务
16:35:49.321 [main] ERROR org.jeecg.modules.Test - 拒绝执行16
16:35:49.351 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 3
16:35:49.351 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 5
16:35:49.351 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 4
16:35:49.351 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 6
16:35:49.351 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 2
16:35:50.365 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 11
16:35:50.365 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 12
16:35:50.369 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 14
16:35:50.365 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 13
16:35:50.369 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 15
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 继续执行16
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 第17个任务
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 第18个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第19个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第20个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第21个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第22个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第23个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第24个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第25个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第26个任务
16:35:51.334 [main] ERROR org.jeecg.modules.Test - 拒绝执行26
16:35:52.348 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 18
16:35:52.348 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 19
16:35:52.348 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 16
16:35:52.348 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 20
16:35:52.348 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 17
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 继续执行26
16:35:53.349 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 24
16:35:53.349 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 25
16:35:53.349 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 23
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:53.349 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 21
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第27个任务
16:35:53.349 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 22
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第28个任务
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第29个任务
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.350 [main] DEBUG org.jeecg.modules.Test - 第30个任务
16:35:53.350 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:54.353 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 27
16:35:54.353 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 29
16:35:54.353 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 30
16:35:54.353 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 26
16:35:54.353 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 28