Bhupesh Subramaniam
Bhupesh Subramaniam

Reputation: 51

Java thread dump: java.lang.Thread.State: WAITING (on object monitor)

There are a large number of threads from our thread pool waiting for a connection indefinitely because our httpclient doesn't have any timeout.

Thread dump:

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

But we are calling future.cancel(true) with mayInterruptIfRunning flag set to true to kill such long-running threads after some time. These threads are still waiting for connections and are not getting freed up.

Question: Why are these threads not cleaned up by future.cancel? If future.cancel would not free up these threads, What are the alternative steps to kill such kinds of threads waiting for futile?

Adding more information about implementations

I can't share the exact code but providing some mock example

Our ThreadPoolexecutor is having Unbounded LinkedBlockingQueue and our future tasks are all callables and we are using executor.submit(callable) to execute our tasks.

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

}

Upvotes: 3

Views: 2770

Answers (1)

Mikita Harbacheuski
Mikita Harbacheuski

Reputation: 2253

Your threads are waiting on synchronized (connectionPool) monitor in MultiThreadedHttpConnectionManager.doGetConnection which isn't responsible for interruption. According to the documentation of getConnectionWithTimeout increasing number of maxHostConnections and maxTotalConnections can help. It's also possible to specify timeout value in http.connection-manager.timeout which is 0 by default so threads are waiting for connection indefinitely.

/**
 * 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
 */

Upvotes: 1

Related Questions