如何打断未来,但还是等待它完成?

Jes*_*num 6 java multithreading future interrupt

我有一系列的工作,我使用ExecutorService排队.如果用户点击"取消",那么我需要通知这些工作他们应该尽快停止.但是,有时它们处于代码的关键部分,必须在父线程继续之前完成.我怎样才能做到这一点?我不想使用自己的取消标志,因为这不会导致睡眠/等待退出.

我认为这段代码可以工作,但它没有做我想要的:

while( true ) {
    //Do this in a loop. If our thread is interrupted, we call cancel on the threads (to try to get them to hurry up by skipping non-essential stuff), but we still need to wait for them to finish.
    try {
        for( Future<Void> future : futures ) {
            future.get(); //I thought that this would continue waiting, even if I call cancel, but it doesn't. How can I wait for the future to finish?
        }
        break; //OK, everything is finished, exit the wait loop.
    } catch( InterruptedException e ) {
        wasInterrupted = true; //We'll rethrow the exception laster as an AbortException.
        //Need to wait for futures to finish, even if it's canceled.
        log.info( "Attempting to interrupt threads that are reading changes..." );
        for( Future<Void> future : futures ) {
            future.cancel( true ); //I want to tell the threads to 'hurry up' and skip non-essential stuff.
        }
    } catch( ExecutionException e ) {
        throw e.getCause();
    }
}

//I shouldn't get to this line until all futures have finished!
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 4

如何中断 Future,但仍然等待它完成?

有趣的问题。您的代码将无法工作,因为当您取消 a 时Future,正如您所发现的,您无法get()再次调用它,因为这会抛出CancellationException.

如果我理解您的要求:

  • 您需要能够中断线程,因为您想停止sleepwait等等。
  • 您仍然希望能够在取消任务后获取任务的结果。

要做的就是不要这里使用Futures 。相反,使用您自己的作业包装器并等待其ExecutorService本身完成executorService.awaitTermination(...)

如果您需要任务的结果,那么您的Runnable包装类将保存计算结果并有一个boolean done标志。等待线程将等待每个线程Runnable将其done标志设置为 true。当包装器完成其run()方法时,它将自行设置donenotify()。它需要在一个finally块中完成此操作。

如果等待线程被中断,它将调用executorService.shutdownNow(true)中断所有线程,但会继续循环等待它们完成。

类似的事情。