2012-04-05 103 views
3

這是一個簡單的測試程序。主線程啓動一些子線程。我已經添加到主要: Runtime.getRuntime()。addShutdownHook(hookThread);Java:如何及時停止HttpURLConnection.getInputStream?

當在JVM進程上按下^ C時,此hookThread將設置一個全局關閉標誌並調用interrupt()給所有子線程。我想讓所有的子線程都返回,但是如果子線程在HttpURLConnection.getInputStream()中,interrupt()對子線程不做任何事情。子線程在超時(30秒)後返回,這對我來說太拖延了。

什麼是立即中​​斷HttpURLConnection.getInputStream()調用的最佳方式?

以下中斷後的子線程的堆棧的頂部()被調用就可以了:

"Thread-0" prio=10 tid=0x0000000040b0f800 nid=0x3eab runnable [0x000000004211b000] 
    java.lang.Thread.State: RUNNABLE 
     at java.net.SocketInputStream.socketRead0(Native Method) 
     at java.net.SocketInputStream.read(SocketInputStream.java:129) 
     at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) 
     at java.io.BufferedInputStream.read1(BufferedInputStream.java:258) 
     at java.io.BufferedInputStream.read(BufferedInputStream.java:317) 
     - locked <0x00000000fd99ac88> (a java.io.BufferedInputStream) 
     at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687) 
     at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632) 
     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195) 
     - locked <0x00000000fd997670> (a sun.net.www.protocol.http.HttpURLConnection) 
... 

回答

1

你很可能得關閉流。根據Java bug #4514257,在任何InputStream.read()上調用Thread.interrupt()失敗。

+0

您無法關閉尚不存在的流;該線程在調用* get *流時被阻塞。如果你沒有參考它,你怎麼能關閉它? – erickson 2012-04-06 01:46:03

+0

嗯,你說得對。奇怪的是HttpURLConnection.getInputStream()實際上需要從套接字讀取數據。無論如何,Java在read()過程中都會忽略中斷調用,所以您建議使用NIO可能是最好的。 – 2012-04-06 15:23:01

1

您無法中斷此通話。

您可以在進行調用之前設置較短的超時時間,或者您可以通過NIO軟件包找到支持可中斷I/O的HTTP客戶端庫。

此外,你應該只中斷你擁有的線程。如果你創建了進程中的每個線程並理解它們如何響應中斷,那沒問題,但否則盲目中斷線程是危險的。