4

我做了一个观察,我想完全理解它。

首先,我定期进行线程转储并创建线程状态的摘要:

jstack -l 19498 > dump.txt ; awk '/State: / { print }' < dump.txt  | sort | uniq -c

上面命令的结果如下所示:

 70    java.lang.Thread.State: RUNNABLE
  8    java.lang.Thread.State: TIMED_WAITING (on object monitor)
  1    java.lang.Thread.State: TIMED_WAITING (sleeping)
171    java.lang.Thread.State: WAITING (on object monitor)

RUNNABLE= 实际处理 Web 应用程序的请求
TIMED_WAITING= Quartz Scheduler 线程
WAITING= 等待处理即将到来的 HTTP 请求的空闲线程

WAITING 线程示例(所有 WAITING 看起来像这样):

"http-80-178" daemon prio=10 tid=0x00007fa8c0bbe000 nid=0x2e11 in Object.wait() [0x00007fa8aaae9000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00007fa8e6b873c8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458)
        - locked <0x00007fa8e6b873c8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484)
        at java.lang.Thread.run(Thread.java:619)

   Locked ownable synchronizers:
        - None

Tomcat 配置

我的 Tomcat 配置参数使用的是默认值,意思是

minSpareThreads = 25(因此 Tomcat 确保有 25 个线程准备好处理 maxThreads = 200(200 个请求可以在没有警告的情况下并行处理)
acceptCount = 100(如果所有 200 个线程都忙,HTTP 连接器可以排队额外的 100 个请求)

问题

当我定期执行命令时,我看到线程总数正在增加。没有BLOCKING线程。

我不明白为什么线程数在增加,因为WAITING状态中有很多很多线程,准备处理另一个 HTTP 请求。

我还看到RUNNABLE+WAITING在一段时间内(例如 1 小时)是恒定的,但随后它增加了 5 或 6 并再次保持不变。似乎线程池越来越大,直到达到限制,Tomcat关闭......

这些TIMED_WAITING线程很可能来自运行在同一个 JVM 中的 Quartz 调度程序。

我对值的解释不正确吗?

4

1 回答 1

2

你读过这篇文章吗?引用一个小章节:

由于 java ThreadPoolExecutor 的 FIFO 行为,每个线程至少会等待“maxIdleTime”的新任务,然后才能关闭。此外,再次由于线程池的 FIFO 行为,要关闭线程,需要至少等于maxIdleTime的时间段没有任何 请求进入

于 2013-01-22T18:16:45.300 回答