java - 并发框架中shutdownNow的使用

标签 java executorservice java.util.concurrent executors

如果我使用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)shutdownNowRunnable 完美配合。

以下是我编写的测试代码:

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

底线是 invokeAllFuture.get 是阻塞操作。有人可以验证一下吗?

最佳答案

您提交给 ThreadPoolExecutorRunnbaleCallable 都将被包装为 java.util.concrrent.FutureTask并执行。

在本例中,在 SingleRunnableWorkerSingleCallableWorker 中,当任务被 Thread.sleep(10000) 阻塞时,executorService .shutdownNow() 将导致立即抛出 InterruptedException。

但是,

    SingleRunnableWorker.run() 中抛出的
  • InterruptedException 是 强制立即捕获并由 e.printStackTrace() 处理。
  • InterruptedExceptionSingleCallableWorker.call() 中抛出 被 FutureTask 中的内部同步器捕获,同步器只是 记录InterruptedException并返回。当调用 future.get() 时, InterruptedException 将被包装为 ExecutionException 并且 重新抛出。

关于java - 并发框架中shutdownNow的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38463538/

相关文章:

java - ExecutorService 和 Lambdas - .execute(() -> ...) 和 .execute() 之间的区别

Java 线程在处理结束时变慢

java - JSP - Netbeans 无法使用 session bean

java - 异常处理 ScheduledExecutorService

java - (处理)将类型文件转换为类型字符串?

java - 来自 ExecutorService 的 CompletableFuture

Java ExecutorService 作为实现细节

java - 为什么 Java 的 SimpleDateFormat 解析这个

java - 使用内在锁进入 block

java - 一般将不同的参数传递给方法