【问题标题】:Java thread dump: java.lang.Thread.State: WAITING (on object monitor)Java 线程转储:java.lang.Thread.State: WAITING(在对象监视器上)
【发布时间】:2017-12-21 14:40:22
【问题描述】:

我们的线程池中有大量线程无限期地等待连接,因为我们的 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) 时将 ma​​yInterruptIfRunning 标志 设置为 true 以在一段时间后终止此​​类长时间运行的线程。这些线程仍在等待连接并且没有被释放。

问题: 为什么这些线程没有被 future.cancel 清理?如果future.cancel 不会释放这些线程,有什么替代步骤可以杀死这种等待徒劳的线程?

添加有关实施的更多信息

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

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

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

}

【问题讨论】:

  • 导致这个的代码是什么?您能否发布它,以便我们对此有更好的了解,以及为您实施 future.cancel 的位置。
  • 你为什么不为你的 httpclient 设置超时而不是手动杀死?同一个主题:stackoverflow.com/questions/21445224/…

标签: java multithreading


【解决方案1】:

您的线程正在 MultiThreadedHttpConnectionManager.doGetConnection 中的 synchronized (connectionPool) 监视器上等待,该监视器不负责中断。根据getConnectionWithTimeout 的文档,越来越多的maxHostConnectionsmaxTotalConnections 可以提供帮助。也可以在http.connection-manager.timeout 中指定超时值,默认为 0,因此线程无限期地等待连接。

/**
 * Gets a connection or waits if one is not available.  A connection is
 * available if one exists that is not being used or if fewer than
 * maxHostConnections have been created in the connectionPool, and fewer
 * than maxTotalConnections have been created in all connectionPools.
 *
 * @param hostConfiguration The host configuration specifying the connection
 *        details.
 * @param timeout the number of milliseconds to wait for a connection, 0 to
 * wait indefinitely
 *
 * @return HttpConnection an available connection
 *
 * @throws HttpException if a connection does not become available in
 * 'timeout' milliseconds
 * 
 * @since 3.0
 */

【讨论】:

  • 那么,您是说如果我们错过了设置超时,就没有办法杀死或清理等待同步(connectionPool)的线程?
  • 不幸的是,是的。这样的实现对我来说看起来很可疑,可能尝试其他 http 客户端库(例如 org.apache.httpcomponents)是有意义的
猜你喜欢
  • 2014-10-31
  • 1970-01-01
  • 2018-08-27
  • 2017-02-26
  • 2012-08-03
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多