如果我使用Futures
,例如
List<Future<String>> results = executorService.invokeAll(tasks);
或
Future<String> res = executorService.submit(new SingleWorker());
System.out.println(res.get());
系统等待任务完成。
即使我在上述语句之后有 executorService.shutdownNow();
,我真的不明白系统何时会强制终止文档中提到的现有线程,因为系统直到任务完成并返回 future 为止,永远不会到达该线。
我错过了什么吗?是否有不同的测试用例场景来测试它?
shutdownNow
仅适用于 Runnable
,即当我们说
executorService.submit(new MyRunnable())
?
编辑:
我尝试了一些不同的事情并发现
a)shutdownNow
不适用于 invokeAll
。
b)shutdownNow
如果在 Future.get
之后出现,则语句 shutdownNow
将被阻止直到 Future
已解决(如果是 Callable
)。
c)shutdownNow
与 Runnable
完美配合。
以下是我编写的测试代码:
class SingleRunnableWorker implements Runnable {
@Override
public void run() {
System.out.println("SingleRunnableWorker Running..");
try {
Thread.sleep(10000);
System.out.println("SingleRunnableWorker Running after sleep..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class SingleCallableWorker implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("SingleCallableWorker Calling..");
Thread.sleep(10000);
System.out.println("SingleCallableWorker Calling after sleep..");
return "SingleCallableWorker Calling done";
}
}
我正在测试它如下:
ExecutorService executorService = Executors.newFixedThreadPool(4);
/*List<Future<String>> results = */executorService.invokeAll(tasks);//blocks by default
Future<String> res = executorService.submit(new SingleCallableWorker());
//System.out.println(res.get()); //blocks if uncommented
executorService.submit(new SingleRunnableWorker());
executorService.shutdownNow();
其中任务都是Callables
。
底线是 invokeAll
和 Future.get
是阻塞操作。有人可以验证一下吗?
最佳答案
您提交给 ThreadPoolExecutor
的 Runnbale
和 Callable
都将被包装为 java.util.concrrent.FutureTask
并执行。
在本例中,在 SingleRunnableWorker
和 SingleCallableWorker
中,当任务被 Thread.sleep(10000)
阻塞时,executorService .shutdownNow()
将导致立即抛出 InterruptedException。
但是,
-
在
InterruptedException
是 强制立即捕获并由e.printStackTrace()
处理。InterruptedException
在SingleCallableWorker.call()
中抛出 被FutureTask
中的内部同步器捕获,同步器只是 记录InterruptedException并返回。当调用 future.get() 时, InterruptedException 将被包装为 ExecutionException 并且 重新抛出。
SingleRunnableWorker.run()
中抛出的 关于java - 并发框架中shutdownNow的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38463538/