對不起,我必須打開一個新線程來描述此問題。無法停止使用ExecutorService啓動的任務
今天早上我問了this question,有一些答覆,但我的問題仍然沒有解決。
這一次,我會附加一些可運行的代碼(簡化,但同樣的問題)爲您重現該問題:
public class ThreadPoolTest {
public static void main(String[] args) throws Exception {
final ExecutorService taskExecutor = Executors.newFixedThreadPool(5);
Future<Void> futures[] = new Future[5];
for (int i = 0; i < futures.length; ++i)
futures[i] = startTask(taskExecutor);
for (int i = 0; i < futures.length; ++i)
System.out.println("futures[i].cancel(true): " + futures[i].cancel(true));
System.out.println("Cancel DONE.");
taskExecutor.shutdown();
}
private static Future<Void> startTask(final ExecutorService taskExecutor) {
Future<Void> f = taskExecutor.submit(new Callable<Void>() {
public Void call() throws Exception {
try {
downloadFile(new URI("http://stackoverflow.com"));
while(true) {
System.out.println(Thread.currentThread().getName() + ": " + Thread.currentThread().isInterrupted());
if(Thread.currentThread().isInterrupted())
break;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
});
return f;
}
private static void downloadFile (final URI uri) throws Exception {
// if(true) return;
Socket socket = new Socket (uri.getHost(), uri.getPort() == -1 ? 80 : uri.getPort());
return;
}
}
上面的代碼很有可能會陷入無限循環(您可能希望多次運行代碼以見證我所看到的),正如你可以在主要方法中看到的那樣,我爲所有任務調用futures [i] .cancel(true),我不知道爲什麼會發生這種情況,一直在折磨我一天以上。
您的幫助將不勝感激。
您的問題可能與許多IO方法(網絡或磁盤)無法處理中斷有關。您可能需要在downloadFile中註釋掉套接字行並查看會發生什麼情況。此外,「陷入無限循環」的含義並不清楚:它是否會打印出線號或堵塞? – toto2 2011-12-26 15:40:20
是的,如果我註釋掉套接字線,它按預期工作並且任務被正確取消。通過「陷入一個無限循環」我的意思是它不斷打印出線程名稱,這意味着Thread.currentThread()。isInterrupted()一直返回false。現在你已經指出了IO方法不能處理中斷的事實(我不知道),有沒有辦法在call()方法中攔截中斷,然後取消任務?現在套接字線似乎吞噬了我的中斷異常。 – neevek 2011-12-26 16:08:24
我搜索了一下,看起來Socket的行爲沒有被定義爲中斷,而且一些不同的JVM有不同的行爲。 – toto2 2011-12-26 17:22:14