Java线程转储:java.lang.Thread.State:WAITING(在对象监视器上)

时间:2017-12-21 14:40:22

标签: java multithreading

我们的线程池中有大量线程无限期地等待连接,因为我们的httpclient没有任何超时。

线程转储:

"pool-18-thread-400" #471 prio=5 os_prio=0 tid=0x00007fdf37a61000 nid=0x6ed7 in Object.wait() [0x00007fde8df9e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007263acb18> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool)
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.doGetConnection(Unknown Source)
    - locked <0x00000007263acb18> (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool)
    at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.getConnectionWithTimeout(Unknown Source)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(Unknown Source)
    at org.apache.commons.httpclient.HttpClient.executeMethod(Unknown Source)

但我们将 future.cancel(true) mayInterruptIfRunning标志设置为true,以便在一段时间后终止这些长时间运行的线程。这些线程仍在等待连接,并且没有被释放。

问题:  为什么 future.cancel 不清除这些线程?如果future.cancel不会释放这些线程,那么杀死这类等待无用的线程的替代步骤是什么?

添加有关实施的更多信息

我无法分享确切的代码,但提供了一些模拟示例

我们的ThreadPoolexecutor拥有Unbounded LinkedBlockingQueue,我们未来的任务都是callables,我们正在使用executor.submit(callable)来执行我们的任务。

public class MockThreadPoolExecutor extends ThreadPoolExecutor {
    public MockThreadPoolExecutor(int numThread) {
        super(numThread,numThread, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        prestartAllCoreThreads();
    }

}

1 个答案:

答案 0 :(得分:1)

您的帖子正在synchronized (connectionPool) MultiThreadedHttpConnectionManager.doGetConnection的{​​{1}}监视器上等待,并且不对中断负责。根据{{​​1}}的文档,越来越多的getConnectionWithTimeoutmaxHostConnections可以提供帮助。它也可以在maxTotalConnections中指定超时值,默认为0,因此线程无限期地等待连接。

http.connection-manager.timeout