Java线程 - 奇怪的Thread.interrupted()和future.cancel(true)行为

mar*_*rts 5 java multithreading future interrupt threadpool

我想管理由TaskExecutor返回的Futures对象列表.
我有这样的事情

 List<Future<String>> list 

 void process(ProcessThis processThis) {     
    for ( ...) {
       Future<String> future = taskExecutor.submit(processThis);
       list.add(future)
    }
 }


 void removeFutures() {
    for(Future future : list) {
       assert future.cancel(true);
 }
Run Code Online (Sandbox Code Playgroud)

ProcessThis是一个实现Callable <String>并检查Thread.interrupted()状态的任务

    public String call() {
        while (true) {
            if (Thread.interrupted()) {
                break;
            }
            doSomething();
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在的问题是,当调用Thread.interrupted()时,只有并发线程的子集返回'true'.
removeFutures()中的断言为每个被删除的未来返回true(我也检查了isDone()和isCompleted().
被中断的线程数是随机的.超过15个运行线程有时13个被中断,有时2个... .
我真的不明白的地方是个问题.如果我叫future.cancel(真),并返回true ...然后我检查Thread.interrupted(这被称为只有一次),我希望这回也是如此.
我错过了什么你知道吗?

我在构建Java 1.6.0_02-B05

Kev*_*vin 6

请注意,Thread.interrupted()返回当前中断的状态,然后清除它,因此所有将来的调用都将返回false.你想要的可能是什么Thread.currentThread().isInterrupted().

另请注意,future.cancel(true)如果任务已经完成或取消,通常只会返回false.如果返回true,则无法保证任务实际将被取消.

发生了什么事doSomething()?由于中断,RuntimeException可能会在某处转义.你有UncaughtExceptionHandler设置吗?如果没有,你需要传递一个ThreadFactoryExecutor设置异常处理程序并记录任何错过的异常.


axt*_*avt 2

至少,你应该恢复中断标志以使taskExecutor知道线程中断:

public String call() { 
    while (true) { 
        if (Thread.interrupted()) { 
            Thread.currentThread().interrupt();
            break; 
        } 
        doSomething(); 
    } 
} 
Run Code Online (Sandbox Code Playgroud)