SO上有一些答案,但是我正在寻找使用我的代码的解决方案,以便清楚地理解。
我已经使用Executor创建了工作线程,执行工作后,工作人员会将结果返回给调用方(主要)
工人
public class Worker implements Runnable {
private final int num;
public Worker(int num) {
this.num = num;
}
@Override
public void run() {
System.out.println("Starting job: " + num);
try {
Thread.sleep(2000);
System.out.println("end job:" + num);
String result = "result " + num; // how to pass all the results back to the caller
} catch (Exception e) {
e.printStackTrace();
}
}
}
工人测试
public class WorkerTest {
private static List<String> result = new ArrayList<>();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new Worker(i);
executorService.execute(worker);
}
executorService.shutdown();
while(!executorService.isTerminated());
}
}
答案 0 :(得分:1)
这是您的完整代码 公共类WorkerTest { 私有静态列表结果= new ArrayList <>();
public static void main(String[] args) throws Exception {
Future[] futures = new Future[10];
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Callable worker = new Worker(i);
futures[i] = ex.submit(worker);
}
for (int i = 0; i < 10; i++) {
String resultString = (String) futures[i].get();
System.out.println(resultString);
}
ex.shutdown();
while (!ex.isTerminated());
}
}
class Worker implements Callable<String> {
private final int num;
public Worker(int num) {
super();
this.num = num;
}
@Override
public String call() throws Exception {
String result = null;
System.out.println("starting job " + num);
try {
Thread.sleep(2000);
System.out.println("end job " + num);
result = "result" + num;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
或者,如果您要将结果存储在列表中,也可以这样做。
public class ExecutorTest {
private static List<String> result = new ArrayList<>();
public static void main(String[] args) throws Exception {
ExecutorService ex = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Callable worker = new Worker(i);
Future<String> stringResult= ex.submit(worker);
String output = stringResult.get();
result.add(output);
System.out.println(output);
}
ex.shutdown();
while (!ex.isTerminated());
System.out.println("All results received frmo executor service ");
System.out.println(result);
}
}
答案 1 :(得分:0)
您应该实现Callable
而不是实现Runnable
,然后使用返回Future
的方法
public class Worker implements Callable<String> {
@Override
public String call() {
return "123";
}
}
ExecutorService es = Executors.newFixedThreadPool(5);
Future<?> f = es.submit(new Worker());
String result = f.get(); // 123
答案 2 :(得分:0)
>我不能把头放在[未来]上。
也许幕后的一瞥会有所帮助
Future
是一个接口,但是有一些标准的库类,implements Future
是我们不知道的名称。假设它叫FutureImpl
。
FutureImpl
实例具有一个由Future
API指定的get()
方法,并且它具有另一个我们看不到的方法,但我们将其称为put(x)
当Karol Dowbecki的示例代码将任务提交给执行者服务时,执行者服务将创建一个新的FutureImpl
实例并对其执行以下两项操作:
它从es.submit(...)
调用中返回引用。
Future<?> f = es.submit(...);
工作线程将调用您赋予它的任务函数,然后它将获取返回的值,并将其存储在FutureImpl
对象中:
futureImpl.put(task.Call());
注意!
f
和futureImpl
是同一对象的两个不同名称。唯一的区别是,工作线程知道它是FutureImpl
类的实例,而主线程只知道它是implements Future
类的某个实例。
无论如何,回到主线程...它可以在工作人员正在执行其工作时做其他事情,然后最终,主线程可以尝试检索该值:
String result = f.get();
如果任务已经完成,并且工作线程已经在主线程调用futureImpl.put(...)
之前调用了f.get()
,那么f.get()
将立即返回该值。但是,如果主线程首先调用f.get()
,那么get()
调用将等待,直到辅助线程完成任务并存储值。