0

如果我使用Futures喜欢

List<Future<String>> results = executorService.invokeAll(tasks); 

或者

Future<String> res = executorService.submit(new SingleWorker());
System.out.println(res.get());

系统等待任务完成。

即使我executorService.shutdownNow();在上面提到的语句之后,我真的不明白系统何时会强制终止文档中提到的现有线程,因为系统在任务完成并返回未来之前永远不会到达线路。我错过了什么吗?是否有不同的测试用例场景来测试它?

shutdownNow仅当我们Runnable说 ie 时才 有效?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正在阻止操作。有人可以验证吗?

4

1 回答 1

1

RunnbaleCallable您提交的两者都ThreadPoolExecutor将被包装java.util.concrrent.FutureTask并执行。

在这种情况下,在SingleRunnableWorkerSingleCallableWorker中,当任务被 阻塞时Thread.sleep(10000)executorService.shutdownNow()会立即引发 InterruptedException。

但,

  • InterruptedException被扔进SingleRunnableWorker.run()去的人必须立即被抓住并由 处理 e.printStackTrace()
  • InterruptedException抛出的SingleCallableWorker.call()将被内部同步器捕获FutureTask,同步器只记录 InterruptedException 并返回。当future.get()被调用时,InterruptedException 将被包装为 ExecutionException 并重新抛出。
于 2017-12-03T07:39:19.063 回答