I'm developing a Java application that performs multiple API calls concurrently, each within its own thread. I've encountered significant delays in response times, with some calls taking minutes to complete. A thread dump showed that several threads are BLOCKED, waiting to acquire a monitor lock on sun.net.www.http.KeepAliveCache.put. Below is a snippet from the stack trace:
"Thread-613" #844 prio=5 os_prio=0 tid=0x000001c8dfd23800 nid=0x45c waiting for monitor entry [0x000000c8a66fe000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.net.www.http.KeepAliveCache.put(KeepAliveCache.java:80)
- waiting to lock <0x00000005c0027448> (a sun.net.www.http.KeepAliveCache)
at sun.net.www.protocol.https.HttpsClient.putInKeepAliveCache(HttpsClient.java:659)
at sun.net.www.http.HttpClient.finished(HttpClient.java:395)
at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:97)
at sun.net.www.MeteredStream.justRead(MeteredStream.java:93)
at sun.net.www.MeteredStream.read(MeteredStream.java:135)
- locked <0x000000062e959300> (a sun.net.www.http.KeepAliveStream)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3456)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x000000062eaa9138> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.read(BufferedReader.java:182)
- locked <0x000000062eaa9138> (a java.io.InputStreamReader)
The application is designed to handle multiple simultaneous API requests efficiently, presumably using a thread pool, but this blocking behavior is causing significant performance issues.
Environment:
- Java Version: OpenJDK 1.8.0_392
Attempts to resolve the issue:
- Updated to the latest version of OpenJDK (1.8.0_392), but the issue persists.
- Disabled keep-alive with
-Dhttp.keepAlive=false, which resulted in threads now blocking onsun.net.www.http.KeepAliveCache.get(KeepAliveCache.java:156).
Question:
Could the use of alternative HTTP clients like OkHTTP mitigate this issue, or would they encounter similar blocking behavior due to the underlying library? Additionally, what are some potential causes for KeepAliveCache.put to become a bottleneck, and how might I address them?