Java 如何正确处理SSLSocketImpl死锁?

Java 如何正确处理SSLSocketImpl死锁?,java,wikipedia-api,Java,Wikipedia Api,使用时很少会出现死锁。查看完整的线程转储(通过kill-3$JAVA-PID获取)表明死锁似乎起源于SSLSocketImpl中的某个地方。我更愿意首先避免这种僵局(而不是进行一些黑客恢复),但我不确定如何找到原因并防止它。有没有办法在SSLSocketImpl中设置超时或在死锁情况下引发异常?(在主循环中捕获它并重做最后一个调用将非常简单) 完整线程转储OpenJDK 64位服务器VM(24.51-b03混合模式): “服务线程”守护进程prio=10 tid=0x00007f3cd816b0

使用时很少会出现死锁。查看完整的线程转储(通过
kill-3$JAVA-PID
获取)表明死锁似乎起源于SSLSocketImpl中的某个地方。我更愿意首先避免这种僵局(而不是进行一些黑客恢复),但我不确定如何找到原因并防止它。有没有办法在SSLSocketImpl中设置超时或在死锁情况下引发异常?(在主循环中捕获它并重做最后一个调用将非常简单)

完整线程转储OpenJDK 64位服务器VM(24.51-b03混合模式):
“服务线程”守护进程prio=10 tid=0x00007f3cd816b000 nid=0x102c runnable[0x0000000000000000]
java.lang.Thread.State:可运行
“C2编译器线程1”守护程序prio=10 tid=0x00007f3cd8168800 nid=0x102b等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“C2编译器线程0”守护程序prio=10 tid=0x00007f3cd8165800 nid=0x102a等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“信号调度器”守护程序prio=10 tid=0x00007f3cd8163800 nid=0x1029等待条件[0x0000000000000000]
java.lang.Thread.State:可运行
“终结器”守护程序prio=10 tid=0x00007f3cd8140800 nid=0x1028等待条件[0x00007f3ccb9f7000]
java.lang.Thread.State:等待(停车)
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.locks.ReentrantLock$NonfairSync)
位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
位于java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
位于java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
位于java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
位于sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:799)
位于sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:672)
位于sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:2005)
位于sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1832)
位于sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1600)
-锁定(sun.security.ssl.SSLSocketImpl)
位于sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1538)
位于sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
位于java.lang.ref.Finalizer.invokeFinalizeMethod(本机方法)
位于java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
位于java.lang.ref.Finalizer.access$100(Finalizer.java:32)
位于java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190)
对象中的“引用处理程序”守护程序prio=10 tid=0x00007f3cd813e800 nid=0x1027等待()[0x00007f3ccbaf9000]
java.lang.Thread.State:正在等待(在对象监视器上)
在java.lang.Object.wait(本机方法)
-等待(java.lang.ref.Reference$Lock)
等待(Object.java:503)
在java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
-锁定(一个java.lang.ref.Reference$Lock)
“主”优先级=10 tid=0x00007f3cd8008000 nid=0x1021等待监视器输入[0x00007f3cdfdb7000]
java.lang.Thread.State:阻塞(在对象监视器上)
位于sun.security.ssl.SSLSocketImpl.getConnectionState(SSLSocketImpl.java:649)
-等待锁定(sun.security.ssl.SSLSocketImpl)
位于sun.security.ssl.SSLSocketImpl.isClosed(SSLSocketImpl.java:1446)
位于java.net.Socket.getTcpNoDelay(Socket.java:965)
位于sun.security.ssl.BaseSSLSocketImpl.getTcpNoDelay(BaseSSLSocketImpl.java:345)
位于sun.security.ssl.SSLSocketImpl.WriterCordinternal(SSLSocketImpl.java:819)
位于sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
位于sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
-锁定(sun.security.ssl.AppOutputStream)
位于java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
位于java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
-锁定(java.io.BufferedOutputStream)
位于java.io.PrintStream.flush(PrintStream.java:338)
-锁定(一个java.io.PrintStream)
在sun.net.www.MessageHeader.print上(MessageHeader.java:297)
-锁定(sun.net.www.MessageHeader)
http.HttpClient.writeRequests(HttpClient.java:599)
位于sun.net.www.http.HttpClient.writeRequests(HttpClient.java:610)
位于sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:619)
位于sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1321)
-锁定(sun.net.www.protocol.https.DelegateHttpsURLConnection)
在sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2731)上
位于sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:307)
位于shared.Wiki.grabbookies(Wiki.java:6907)
位于shared.Wiki.fetch(Wiki.java:6462)
位于shared.Wiki.getPageText(Wiki.java:1465)
位于smallBots.Bot1.getText(Bot1.java:204)
位于smallBots.Bot1.crawlcogory(Bot1.java:74)
位于smallBots.Bot1.main(Bot1.java:49)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
在org.eclipse.jdt.internal.jarinjarloader.JarRsrcLo
Full thread dump OpenJDK 64-Bit Server VM (24.51-b03 mixed mode):

"Service Thread" daemon prio=10 tid=0x00007f3cd816b000 nid=0x102c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007f3cd8168800 nid=0x102b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007f3cd8165800 nid=0x102a waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007f3cd8163800 nid=0x1029 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007f3cd8140800 nid=0x1028 waiting on condition [0x00007f3ccb9f7000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007d77a9080> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:799)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:672)
        at sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:2005)
        at sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1832)
        at sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1600)
        - locked <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1538)
        at sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
        at java.lang.ref.Finalizer.access$100(Finalizer.java:32)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190)

"Reference Handler" daemon prio=10 tid=0x00007f3cd813e800 nid=0x1027 in Object.wait() [0x00007f3ccbaf9000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000078495a2c8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:503)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
        - locked <0x000000078495a2c8> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x00007f3cd8008000 nid=0x1021 waiting for monitor entry [0x00007f3cdfdb7000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at sun.security.ssl.SSLSocketImpl.getConnectionState(SSLSocketImpl.java:649)
        - waiting to lock <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.isClosed(SSLSocketImpl.java:1446)
        at java.net.Socket.getTcpNoDelay(Socket.java:965)
        at sun.security.ssl.BaseSSLSocketImpl.getTcpNoDelay(BaseSSLSocketImpl.java:345)
        at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:819)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
        - locked <0x00000007d77a8d60> (a sun.security.ssl.AppOutputStream)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        - locked <0x00000007d77a8d48> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.flush(PrintStream.java:338)
        - locked <0x00000007d77a8d28> (a java.io.PrintStream)
        at sun.net.www.MessageHeader.print(MessageHeader.java:297)
        - locked <0x00000007d6d057b0> (a sun.net.www.MessageHeader)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:599)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:610)
        at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:619)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1321)
        - locked <0x00000007d6d05640> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2731)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:307)
        at shared.Wiki.grabCookies(Wiki.java:6907)
        at shared.Wiki.fetch(Wiki.java:6462)
        at shared.Wiki.getPageText(Wiki.java:1465)
        at smallBots.Bot1.getText(Bot1.java:204)
        at smallBots.Bot1.crawlCategory(Bot1.java:74)
        at smallBots.Bot1.main(Bot1.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

"VM Thread" prio=10 tid=0x00007f3cd813a000 nid=0x1026 runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f3cd801d800 nid=0x1022 runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f3cd801f800 nid=0x1023 runnable 

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f3cd8021800 nid=0x1024 runnable 

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f3cd8023000 nid=0x1025 runnable 

"VM Periodic Task Thread" prio=10 tid=0x00007f3cd8175800 nid=0x102d waiting on condition 

JNI global references: 205


Found one Java-level deadlock:
=============================
"Finalizer":
  waiting for ownable synchronizer 0x00000007d77a9080, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "main"
"main":
  waiting to lock monitor 0x00007f3cac0015c8 (object 0x00000007d77a8d78, a sun.security.ssl.SSLSocketImpl),
  which is held by "Finalizer"

Java stack information for the threads listed above:
===================================================
"Finalizer":
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007d77a9080> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:799)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:672)
        at sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:2005)
        at sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1832)
        at sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1600)
        - locked <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1538)
        at sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
        at java.lang.ref.Finalizer.access$100(Finalizer.java:32)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190)
"main":
        at sun.security.ssl.SSLSocketImpl.getConnectionState(SSLSocketImpl.java:649)
        - waiting to lock <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.isClosed(SSLSocketImpl.java:1446)
        at java.net.Socket.getTcpNoDelay(Socket.java:965)
        at sun.security.ssl.BaseSSLSocketImpl.getTcpNoDelay(BaseSSLSocketImpl.java:345)
        at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:819)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
        - locked <0x00000007d77a8d60> (a sun.security.ssl.AppOutputStream)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        - locked <0x00000007d77a8d48> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.flush(PrintStream.java:338)
        - locked <0x00000007d77a8d28> (a java.io.PrintStream)
        at sun.net.www.MessageHeader.print(MessageHeader.java:297)
        - locked <0x00000007d6d057b0> (a sun.net.www.MessageHeader)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:599)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:610)
        at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:619)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1321)
        - locked <0x00000007d6d05640> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2731)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:307)
        at shared.Wiki.grabCookies(Wiki.java:6907)
        at shared.Wiki.fetch(Wiki.java:6462)
        at shared.Wiki.getPageText(Wiki.java:1465)
        at smallBots.Bot1.getText(Bot1.java:204)
        at smallBots.Bot1.crawlCategory(Bot1.java:74)
        at smallBots.Bot1.main(Bot1.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

Found 1 deadlock.

Heap
 PSYoungGen      total 10752K, used 801K [0x00000007d6d00000, 0x00000007d7880000, 0x0000000800000000)
  eden space 9728K, 1% used [0x00000007d6d00000,0x00000007d6d1fc20,0x00000007d7680000)
  from space 1024K, 65% used [0x00000007d7780000,0x00000007d7828b40,0x00000007d7880000)
  to   space 1024K, 0% used [0x00000007d7680000,0x00000007d7680000,0x00000007d7780000)
 ParOldGen       total 93696K, used 69956K [0x0000000784800000, 0x000000078a380000, 0x00000007d6d00000)
  object space 93696K, 74% used [0x0000000784800000,0x0000000788c51160,0x000000078a380000)
 PSPermGen       total 21504K, used 9537K [0x000000077a200000, 0x000000077b700000, 0x0000000784800000)
  object space 21504K, 44% used [0x000000077a200000,0x000000077ab50720,0x000000077b700000)