1. final ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 4,
  2. 60L, TimeUnit.SECONDS,
  3. new ArrayBlockingQueue<>(1), new DefaultThreadFactory("cc"),
  4. (r, executor) -> {
  5. System.out.println("拒绝执行:" + r.toString());
  6. });

如上是一个常见的线程池初始化方式. 使用到了线程池 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 {
  1. public static void main(String[] args) throws Exception {
  2. final ThreadPoolExecutor executorService = new ThreadPoolExecutor(2, 4,
  3. 60L, TimeUnit.SECONDS,
  4. new ArrayBlockingQueue<>(1), new DefaultThreadFactory("cc"),
  5. (r, executor) -> {
  6. System.out.println("拒绝执行:" + r.toString());
  7. });
  8. executorService.submit(ThreadPoolTest::asleep);//core
  9. executorService.submit(ThreadPoolTest::asleep);//core
  10. executorService.submit(ThreadPoolTest::asleep);//queue
  11. executorService.submit(ThreadPoolTest::asleep);//max
  12. executorService.submit(ThreadPoolTest::asleep);//max
  13. executorService.submit(ThreadPoolTest::asleep);//reject
  14. Thread.sleep(1000000);
  15. }
  16. public static void main() {
  17. final ThreadPoolExecutor executorService =
  18. new ThreadPoolExecutor(2, 2,
  19. 0L, TimeUnit.MILLISECONDS,
  20. new LinkedBlockingQueue<Runnable>(),
  21. new DefaultThreadFactory("c2c"));
  22. executorService.submit(() -> System.out.println("gggod"));
  23. executorService.submit(() -> System.out.println("gggod"));
  24. }
  25. public static void asleep() {
  26. try {
  27. System.out.println(Thread.currentThread().getName());
  28. Thread.sleep(5000L);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. }

}

  1. ====> output
  2. ```java
  3. cc-1-1
  4. cc-1-2
  5. cc-1-3
  6. cc-1-4
  7. 拒绝执行:java.util.concurrent.FutureTask@626b2d4a
  8. cc-1-2

验证keepAliveTime的时候,记得使用 psjstack 命令去观察线程的状态。并结合线程的状态加深对 Thread 的理解。