简体   繁体   中英

New thread from Callable instead of Runnable?

Threads are normally created from Runnable s. Is there a way to create a thread from a Callable ?

public class AddNumImmediately implements Callable {
    private int minRange;
    private int maxRange;
    private Set<Integer> primeNumberList;
    private int step;

    public AddNumImmediately(int minRange, int maxRange, Set<Integer> primeNumberList, int step) {
        this.minRange = minRange;
        this.maxRange = maxRange;
        this.primeNumberList = primeNumberList;
        this.step = step;
    }

    @Override
    public Object call() {
        for (int i = minRange; i <= maxRange; i += step) {
            if (PrimeChecker.isPrimeNumber(i)) {
                primeNumberList.add(i);
            }
        }
        return primeNumberList;
    }
}

And then I try to run my Callable via Thread:

public void setup(int min, int max, int threadNumber) throws InterruptedException {
    Set<Integer> primeNumberList = new LinkedHashSet<>();
    List<Thread> threadList = new ArrayList<>();

    for (int i = 0; i < threadNumber; i++) {
        threadList.add(new Thread(String.valueOf(new AddNumImmediately(min, max, primeNumberList, threadNumber))));
    }
    for (Thread thread : threadList) {
        thread.start();
    }

    for (Thread thread : threadList) {
        thread.join();
    }
    System.out.println(primeNumberList);
}

I know that Callable s can be run by an Executor , but is it possible to somehow run them through Thread ?

You're using Callable wrong. A callable returns a <V> , which will become a Future<V> when submitted via an ExecutorService , if you don't work with them, you pick Runnable .

Callable :

A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call.

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

Runnable

The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run.

https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html

So the proper way with callables would be to return a Set<Integer> and merge these Futures together in your primeNumberList .

Is there a way to create a thread from a Callable?

Short answer: No. The Thread API requires a Runnable not a Callable .

You can work around this with a Runnable wrapper for a Callable , though getting the result from the Callable is a bit messy! A much better idea is to use an ExecutorService . That allows you to avoid the problems of not creating too many threads and (alternatively) managing your own thread pool.

It is work noting that your example doesn't really need a Callable . You are returning a Set that was provided in the AddNumImmediately constructor. The caller could simply keep a reference to that Set object.

You can wrap your Callable with a Runnable . Use this helper function to create Thread from Callable .

public static Thread createThreadFromCallable(@NonNull Callable<?> callable) {
    return new Thread(() -> {
        try {
            callable.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM