繁体   English   中英

每 n 分钟创建一个新线程(java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method))

[英]New thread every n minutes (java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method))

我阅读了所有现有主题,但没有找到解决问题的任何方法。 我用 VisualVM 监控我的 glassfish 服务器,我注意到一些奇怪的行为。 这是屏幕截图:

在此处输入图片说明

java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <3cb9965d> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

如您所见,每 20 分钟创建一个新线程(下一个,将创建 Thread-38,然后是 Thread-39,依此类推)。 这些线程永远不会完成。 我正在使用类 Executors 中的 newSingleThreadExecutor(),它是用 scheduleWithFixedDelay() 调度的,延迟为 100 毫秒,其他代码只是 DB 读/写(所以没有什么特别的,会创建新的等待线程)......有人知道什么可能吗?导致这个问题?

ScheduledExecutorService service = service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                //do something...
            }
        }, 1, readInterval, TimeUnit.MILLISECONDS);

编辑:即使没有将应用程序部署到服务器,也会每 20 分钟创建一次新线程。 有没有人注意到类似的问题? 我还注意到所有新线程都在等待相同的 ID(在本例中为 <3cb9965d>)...

也许你的观察反映了线程池的行为......

如果线程在线程池中空闲了一段时间,它将从线程池中删除

根据您在 glassfish 的 domain.xml 中设置,将创建一个新线程以满足池中的最小线程数。 请注意,如果您没有在 domain.xml 文件中指定它们, glassfish 将使用自己的默认值。

这些线程都具有相同的 ID,因为它们属于同一个线程池

要验证您是否可以将属性idle-thread-timeout-seconds="300" 添加到 domain.xml 中的http-thread-pool并使用 VisualVM 再次检查。

 <thread-pool idle-thread-timeout-seconds="300" name="http-thread-pool"></thread-pool>

以上将空闲线程的超时设置为 5 分钟。 也许您在 domain.xml 中的某处发现了“idle-thread-timeout-seconds="1200”,这可以解释您观察到的 20 分钟间隔...

进一步说明:
如果您查看 domain.xml,您可能会发现以下条目(您的可能不同...):

 [...] <!-- HTTP --> <network-listener protocol="http-listener-1" port="8080" name="http-listener-1" thread-pool="http-thread-pool" transport="tcp"></network-listener> <!--HTTPS --> <network-listener protocol="http-listener-2" port="8181" name="http-listener-2" thread-pool="http-thread-pool" transport="tcp"></network-listener> [...] <!--Threadpools wich can be used by network-listeners--> <thread-pools> <thread-pool name="admin-thread-pool" max-queue-size="256" max-thread-pool-size="50"></thread-pool> <thread-pool name="http-thread-pool"></thread-pool> <thread-pool name="thread-pool-1" max-thread-pool-size="200"></thread-pool> </thread-pools> [...]

如您所见,没有为线程池"http-thread-pool"指定属性。 这意味着 galssfish 将使用自己的默认值。

我的 glassfish 安装 (4.1) 中“http-thread-pool”的默认值具有以下值*:

  • 最大队列大小:4096
  • 最大线程池大小:5
  • 最小线程池大小:5
  • 空闲线程超时:900(秒)

在这种情况下,如果一个线程闲置了 15 分钟,它将从线程池中删除。 由于“Min Thread Pool Size = 5”的值,如果线程数低于 5,则将创建一个新线程。

*您可以进入 glassfish 的管理控制台并打开“配置 -> 服务器配置 -> 线程池”以找出您的默认值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM