invokeAny是取消线程池中的所有线程还是仅取消callables?

时间:2017-06-09 01:05:03

标签: java multithreading executorservice

我正在创建一个固定大小ExecutorService,它将从多个线程访问。

ExecutorService executorService = Executors.newFixedThreadPool(2);

然后我使用相同的invokeAny从两个不同的线程中调用ExecutorService

executorService.invokeAny(listCallables);

因此,在线程池中可能存在从不同线程调用的多个任务。

根据invokeAny文档:

  

在正常或特殊退货时,未完成的任务将被取消。

我的问题是,成功返回invokeAny后,是否会取消线程池中的所有线程,还是仅取消在单独线程中调用的任务?

2 个答案:

答案 0 :(得分:1)

正常返回invokeAny后,线程池将取消所有未完成的任务。你可以参考我的例子:

package com.pechen;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class SleepSecondsCallable implements Callable<String> {
    private String name;

    private int seconds;

    public SleepSecondsCallable(String name, int seconds) {
        this.name = name;
        this.seconds = seconds;
    }

    public String call() throws Exception {
        System.out.println(name + ",begin to execute");

        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            System.out.println(name + " was disturbed during sleeping.");
            e.printStackTrace();
            return name + ",fails to execute";
        }

        return name + ",success to execute";
    }

}

主要班级:

package com.pechen;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Main {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
            ExecutorService executorService = Executors.newFixedThreadPool(3);  

            List<Callable<String>> tasks = new ArrayList<Callable<String>>();  

            tasks.add(new SleepSecondsCallable("t1", 2));  
            tasks.add(new SleepSecondsCallable("t2", 1));  

            String result = executorService.invokeAny(tasks);  
            System.out.println(result);  
            executorService.shutdown();  

    }

}

输出:

t1,begin to execute
t2,begin to execute
t2,success to execute
t1 was disturbed during sleeping.
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Unknown Source)
    at java.util.concurrent.TimeUnit.sleep(Unknown Source)
    at com.pechen.SleepSecondsCallable.call(SleepSecondsCallable.java:20)
    at com.pechen.SleepSecondsCallable.call(SleepSecondsCallable.java:1)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

您可以看到,指定线程t2要休眠1秒钟,t1指定为2.当t2成功返回时,存在中断执行t1

答案 1 :(得分:1)

来自Java Sources中的invokeAny实现:

try {
    ....
} finally {
    for (Future<T> f : futures)
        f.cancel(true);
} 

这意味着invokeAny仅取消已提交给它的callable-s。