InvokeAny cancels all threads in the thread pool or only callers?

I am creating a fixed size ExecutorService

that will be accessed from multiple threads.

ExecutorService executorService = Executors.newFixedThreadPool(2);

      

Then I call invokeAny

from two different threads using the same ExecutorService

.

executorService.invokeAny(listCallables);

      

Thus, there is a possibility that the thread pool might have multiple tasks called from different threads.

According to invokeAny documentation :

On normal or exceptional check-in, tasks that were not completed are canceled.

My question is, after a successful return invokeAny

, will it cancel all threads that are in the thread pool, or will it only cancel the tasks that are called on separate threads?

+3


source to share


2 answers


From invokeAny

implementation in Java Sources:

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

      



This means it invokeAny

only cancels the invoked messages that were sent to it.

+1


source


On normal return invokeAny

, the threadpool will cancel all pending tasks. You can refer to my example:

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";
    }

}

      

Main class:

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();  

    }

}

      



Output:

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)

      

You can see, tell thread t2

to hibernate for 1 second and t1

for 2. When t2

it returns successfully, theadpool intercepts execution t1

.

+1


source







All Articles