final ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 4,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1), new DefaultThreadFactory("cc"),
(r, executor) -> {
System.out.println("拒绝执行:" + r.toString());
});
如上是一个常见的线程池初始化方式. 使用到了线程池 ThreadPoolExecutor
的所有参数.
参数介绍
- corePoolSize 线程池中的核心线程个数(除非设置了allowCoreThreadTimeOut)
- maximumPoolSize 线程池允许的线程最大个数
- keepAliveTime 当线程数大于核心线程,多余线程的存活时间。
- TimeUnit 时间单元(这里用秒,按照具体场景而定)
- workQueue 持有线程池提交的Runnable任务
- threadFactory 用于生成Thread的factory.一定要指定线程名字,jstack排查问题是很重要。
- handler 达到线程的最大数并且队列已满的情况下,如何处理被拒绝的任务,如果执行的任务比较重要,可以交给当前线程执行,同时可以这里打印一下JVM的堆栈。可以留下一个现场,不过堆栈这个比较耗性能,建议是每隔10分钟来一发。
验证
```java import io.netty.util.concurrent.DefaultThreadFactory;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;
/**
- @author luobo.cs@raycloud.com
- @since 2021/7/14 1:32 下午 */ public class ThreadPoolTest {
public static void main(String[] args) throws Exception {
final ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 4,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1), new DefaultThreadFactory("cc"),
(r, executor) -> {
System.out.println("拒绝执行:" + r.toString());
});
executorService.submit(ThreadPoolTest::asleep);//core
executorService.submit(ThreadPoolTest::asleep);//core
executorService.submit(ThreadPoolTest::asleep);//queue
executorService.submit(ThreadPoolTest::asleep);//max
executorService.submit(ThreadPoolTest::asleep);//max
executorService.submit(ThreadPoolTest::asleep);//reject
Thread.sleep(1000000);
}
public static void main() {
final ThreadPoolExecutor executorService =
new ThreadPoolExecutor(2, 2,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
new DefaultThreadFactory("c2c"));
executorService.submit(() -> System.out.println("gggod"));
executorService.submit(() -> System.out.println("gggod"));
}
public static void asleep() {
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
====> output
```java
cc-1-1
cc-1-2
cc-1-3
cc-1-4
拒绝执行:java.util.concurrent.FutureTask@626b2d4a
cc-1-2
验证keepAliveTime的时候,记得使用 ps
和 jstack
命令去观察线程的状态。并结合线程的状态加深对 Thread
的理解。