Reputation: 177
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
?
Upvotes: 1
Views: 2344
Reputation: 1
You cannot create a new thread from callable. That's there. For a new thread, Thread has to come into picture. Being said that you can use FurtureTask with callable and Thread to get your result back. You can try something like this:
FutureTask<String> f1 = new FutureTask<String>(new Callable<String>() {
public String call() throws InterruptedException {
Thread.sleep(1000);
return "A constant from " + Thread.currentThread().getName();
}
});
Thread t = new Thread(f1);
t.start();
System.out.println("Calling Get " + Thread.currentThread().getName());
System.out.println(f1.get());
System.out.println("Got Get");
will give you output as :
Calling Get main
A constant from Thread-0
Got Get
Upvotes: 0
Reputation: 6742
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
.
Upvotes: 2
Reputation: 718946
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.
Upvotes: 2
Reputation: 1599
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();
}
});
}
Upvotes: 0