我阅读了所有现有主题,但我没有找到解决问题的方法。我用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毫秒,其他代码只是数据库读/写(所以没有什么特别的东西可以创建新的等待线程)...有人知道什么可能造成这个问题?
ScheduledExecutorService service = service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
//do something...
}
}, 1, readInterval, TimeUnit.MILLISECONDS);
编辑:即使没有应用程序部署到服务器,每20分钟创建一个新线程。有没有人注意到类似的问题?我还注意到所有新线程都在等待相同的ID(在此示例中&lt; 3cb9965d&gt;)...
答案 0 :(得分:1)
也许你的观察反映了线程池的行为......
如果某个线程在线程池中空闲了一段时间,它将从线程池中删除。
根据您在glassfish的domain.xml 中的设置,将创建一个新线程以满足池中的最小线程数。 请注意,如果您没有在domain.xml文件中指定它们,则glassfish会使用自己的默认值。
线程具有相同的ID,因为它们属于同一个线程池。
验证您是否可以将属性 idle-thread-timeout-seconds =&#34; 300&#34; 添加到 http-thread-pool 中domain.xml并使用VisualVM再次检查它。
<thread-pool idle-thread-timeout-seconds="300" name="http-thread-pool"></thread-pool>
&#13;
以上将空闲线程的超时设置为5分钟。也许你找到&#34; idle-thread-timeout-seconds =&#34; 1200&#34;你的domain.xml中的某个地方,这可以解释你观察到的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>
[...]
&#13;
如您所见,没有为线程池&#34; http-thread-pool&#34; 指定属性。这意味着galssfish将使用自己的默认值。
&#34; http-thread-pool&#34;的默认值在我的glassfish安装(4.1)中有以下值*:
在这种情况下,如果一个线程已空闲15分钟,它将从线程池中删除。由于&#34;最小线程池大小= 5&#34;如果线程数低于5,将创建一个新线程。
*您可以进入glassfish的管理控制台并打开 &#34;配置 - &gt; server-config - &gt;线程池&#34;找出你的默认值。