线程通常从Runnable
s创建。有没有一种方法可以从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;
}
}
然后我尝试通过线程运行Callable:
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);
}
我知道Callable
可以由Executor
运行,但是有可能通过Thread
运行它们吗?
答案 0 :(得分:2)
您使用的Callable
错误。可调用对象返回<V>
,当通过Future<V>
提交时,它将变为ExecutorService
,如果不使用它们,则选择Runnable
。
可通话:
返回结果并可能引发异常的任务。实施者 定义一个没有参数的单一方法,称为call。
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
可运行
Runnable接口应该由其 实例旨在由线程执行。上课必须 定义一个没有参数的方法称为run。
https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html
因此,可调用对象的正确方法是返回一个Set<Integer>
并将这些期货合并到您的primeNumberList
中。
答案 1 :(得分:2)
是否可以通过Callable创建线程?
简短的回答:否。Thread
API要求使用Runnable
而不是Callable
。
您可以使用Runnable
的{{1}}包装器解决此问题,尽管从Callable
获取结果有点混乱!一个更好的主意是使用Callable
。这样就可以避免创建过多线程以及(或者)管理自己的线程池的问题。
注意到您的示例实际上并不需要ExecutorService
是很有意义的。您将返回Callable
构造函数中提供的Set
。调用者可以简单地保留对该AddNumImmediately
对象的引用。
答案 2 :(得分:0)
您可以用Callable
包裹Runnable
。使用此帮助程序功能可从Thread
创建Callable
。
public static Thread createThreadFromCallable(@NonNull Callable<?> callable) {
return new Thread(() -> {
try {
callable.call();
} catch (Exception e) {
e.printStackTrace();
}
});
}
答案 3 :(得分:0)
您不能从可调用对象创建新线程。就在那里。对于一个新线程,线程必须出现。 据说您可以将 FurtureTask 与 callable 和 Thread 一起使用来获取结果。你可以试试这样的:
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");
会给你输出:
调用 Get main
来自 Thread-0 的常量
得到了