如何连接/关闭一个被困的HttpURLConnection

时间:2016-08-04 13:10:03

标签: java io httpurlconnection deadlock

请考虑案例:

  • HttpURLConnection已打开,但未从套接字接收任何数据(例如,由于防火墙配置)。
  • 另一个线程想要因超时而断开连接,但在ChunkedInputStream.close()中被阻止:

    "thread-2" - Thread t@333
       java.lang.Thread.State: BLOCKED
      at sun.net.www.http.ChunkedInputStream.close(ChunkedInputStream.java:746)
      - waiting to lock <2be20ded> (a sun.net.www.http.ChunkedInputStream)
    owned by "thread-1" t@385
      at java.io.FilterInputStream.close(FilterInputStream.java:181)
      at
    sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(HttpURLConnection.java:3409)
      at
    sun.net.www.protocol.http.HttpURLConnection.disconnect(HttpURLConnection.java:2824)
    ...
    
    "thread-1" - Thread t@385
       java.lang.Thread.State: RUNNABLE
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
      at java.net.SocketInputStream.read(SocketInputStream.java:170)
      at java.net.SocketInputStream.read(SocketInputStream.java:141)
      at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
      at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
      at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
      - locked <c9077bc> (a java.io.BufferedInputStream)
      at
    sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:552)
      at
    sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:609)
      at sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:696)
      - locked <2be20ded> (a sun.net.www.http.ChunkedInputStream)
      at java.io.FilterInputStream.read(FilterInputStream.java:133)
      at
    sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3336)
      at java.io.SequenceInputStream.read(SequenceInputStream.java:207)
      at java.io.SequenceInputStream.read(SequenceInputStream.java:207)
      at
    org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.read(Unknown
    Source)
      at org.apache.xerces.impl.io.UTF8Reader.read(Unknown Source)
      at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
      at org.apache.xerces.impl.XMLEntityScanner.skipChar(Unknown Source)
      at
    org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown
    Source)
      at
    org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
    Source)
      at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
      at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
      at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
      at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
      at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
    Source)
      at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
      at
    com.lmax.api.internal.protocol.EventStreamHandler.parseEventStream(EventStreamHandler.java:45)
    ...
       Locked ownable synchronizers:
      - locked <4dbb989f> (a java.util.concurrent.ThreadPoolExecutor$Worker)
    

有没有办法避免死锁? 我找到的唯一解决方法是在readTimeout上指定connectTimeoutjava.net.URLConnection

有什么想法吗?

SUT:Oracle JDK 1.8.0_102

0 个答案:

没有答案