每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))

查看:11086
本文介绍了每n分钟创建一个新线程(java.lang.Thread.State:WAITING at sun.misc.Unsafe.park(Native Method))的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了所有现有的主题,但没有找到解决我的问题的方法。我使用VisualVM监控我的glassfish服务器,并且发现了一些奇怪的行为。这里是截图:





  java.lang.Thread.State:WAITING 
at sun.misc.Unsafe.park(本地方法)
- 停车等待< 3cb9965d> (java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject)$ java.util.concurrent.locks.LockSupport.park处的
(LockSupport.java:175)$ java.util.concurrent.locks处的
。 AbstractQueuedSynchronizer $ ConditionObject.await(AbstractQueuedSynchronizer.java:2039)$ java.util.concurrent.ScheduledThreadPoolExecutor
$ DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor $ DelayedWorkQueue。使用java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)获取(ScheduledThreadPoolExecutor.java:809)
在java.util.concurrent.ThreadPoolExecutor.runWorker处获得
(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)$ b $ 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 $ b $ public void run(){
// do something ...
}
} ,1,readInterval,TimeUnit.MILLISECONDS);

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

解决方案

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



如果一个线程在线程池中空闲了一段时间,它将被删除来自线程池

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



线程拥有所有因为它们属于同一个线程池



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



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



上面设置空闲线程的超时到5分钟。也许你会在你的domain.xml中找到idle-thread-timeout-seconds =1200,这可以解释你观察到的20分钟间隔......



<
如果你看一下domain.xml,你可能会发现下列条目(你可能会有所不同......):



  [...]<! -  HTTP  - >< network-listener protocol =http-listener-1port =8080name =http-listener-1thread-pool =http-thread-pooltransport =tcp>< / network-listener><! -  HTTPS  - >< network-listener protocol =http-listener-2port =8181name =http-listener-2thread-pool =http-thread-pooltransport =tcp>< / network-listener> ; [...]线程池可以被网络监听器使用 - >< thread-pools>< thread-pool name =admin-thread-poolmax-que ue-size =256max-thread-pool-size =50>< / thread-pool> < thread-pool name =http-thread-pool>< / thread-pool> < thread-pool name =thread-pool-1max-thread-pool-size =200>< / thread-pool> < / thread-pools> [...]  

您可以看到没有为线程池http-thread-pool指定的属性。这意味着galssfish将使用它自己的默认值。



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




  • 最大队列大小:4096

  • 最大线程池大小:5

  • 最小线程池大小:5


  • 在这种情况下,如果一个线程有闲置了15分钟,它将从线程池中删除。由于最小线程池大小= 5的值,如果线程数低于5,将创建一个新线程。



    *您可以转到Admin控制台glassfish并打开
    配置 - >服务器配置 - >线程池来找出您的默认值。


    I read all existing topics but I didn't find any solution to my problem. I monitor my glassfish server with VisualVM and I have noticed some strange behaviour. Here is screenshot:

    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)
    

    As you can see new thread is created every 20 minutes (next one, Thread-38 will be created and then Thread-39 and so on). These threads are never finished. I am using newSingleThreadExecutor() from class Executors which is scheduled with scheduleWithFixedDelay() with 100 ms delay, other code is just DB read/write (so nothing special that would create new waiting threads)... Does someone have any idea what may be causing this problem?

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

    EDIT: new threads are created every 20 minutes even no applications are deployed to server. Did anybody notice similar problems? I also noticed that all newly threads are waiting for same ID (in this example <3cb9965d>)...

    解决方案

    Maybe your observation reflects the behaviour of the thread-pool...

    If a thread has been idle for a certain time in the thread-pool it will be removed from the thread-pool.

    Depending on your settings in glassfish's domain.xml a new thread will be created to meet the minimum amount of threads in the pool. Please note that glassfish uses its own default values if you do not specify them in the domain.xml-file.

    The threads have all the same ID because they belong to the same thread-pool.

    To verify that you can add the attribute idle-thread-timeout-seconds="300" to the http-thread-pool in the domain.xml and check it again with VisualVM.

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

    The above sets the timeout for idle threads to 5 minutes. Maybe you find "idle-thread-timeout-seconds="1200" somewhere in your domain.xml, this would explain the 20 minutes intervall you observed...

    Further Explanation:
    If you take a look at the domain.xml you might find following entries (yours might be different...):

       [...]
    
    <!-- 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>
    
    [...]

    As you can see there are no attributes specified for the thread-pool "http-thread-pool". This means that galssfish will use its own default values.

    The default values for the "http-thread-pool" in my glassfish installation (4.1) have follwoing values*:

    • Max Queue Size: 4096
    • Max Thread Pool Size: 5
    • Min Thread Pool Size: 5
    • Idle Thread Timeout: 900 (seconds)

    In this case, if a thread has been idle for 15 minutes, it will be removed from the thread pool. Due to the value of "Min Thread Pool Size = 5" a new thread will be created if the number of threads goes below five.

    *You can go to the Admin console of glassfish and open "Configurations -> server-config -> Thread pools" to find out your default values.

    这篇关于每n分钟创建一个新线程(java.lang.Thread.State:WAITING at sun.misc.Unsafe.park(Native Method))的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆