英文:
ExecutorService submit() - Execute in parallel (non-blocking)
问题
我正在尝试并行运行一个任务。我尝试了以下方法:
在我的构造函数中:
this.executor = Executors.newFixedThreadPool(5);
executor.awaitTermination(10, TimeUnit.SECONDS);
然后我将所有要并行运行的项目添加到列表中:
Future<Map.Entry<Location, SomeData>> result = this.executor.submit(new Sender(entry));
resultList.add(result);
然后我在该列表上进行循环,并使用Future
的get()
函数来执行每个任务 - 这似乎是阻塞的:
for (int i = 0; i < resultList.size(); i++) {
Future<Map.Entry<Location, SomeData>> result = resultList.get(i);
try {
logger.info("[Start] Task" + sendQueue.get(i).getKey() + "-" + i);
entry = result.get();
} catch (InterruptedException e) {
logger.error("中断错误", e);
} catch (ExecutionException e) {
logger.error("线程执行错误", e);
} catch (Exception e) {
logger.error("发送错误", e);
}
if (entry == null) {
logger.error("遥测发送错误");
return;
}
logger.info("[Success] Task" + entry.getKey() + "-" + i);
}
Sender的call()
方法:
@Override
public Map.Entry<Location, Data> call() throws InterruptedException {
Thread.sleep(5000);
return this.entry;
}
我发现每个任务都在其他任务之后执行。我想要并行执行所有任务,并使其非阻塞。
有任何想法我可能漏掉了什么?执行器服务不是用来做这个的吗?
英文:
I'm trying to run a task in parallel. I have tried the following:
In my constructor:
this.executor = Executors.newFixedThreadPool(5);
executor.awaitTermination(10, TimeUnit.SECONDS);
then I add all the items I want to run in parallel to a list:
Future<Map.Entry<Location, SomeData>> result = this.executor.submit(new Sender(entry));
resultList.add(result);
Then I loop on that list and use the get()
function of Future
in order to execute each task - which appears to be blocking:
for (int i = 0; i < resultList.size(); i++) {
Future<Map.Entry<Location, SomeData>> result = resultList.get(i);
try {
logger.info("[Start] Task" + sendQueue.get(i).getKey() + "-" + i);
entry = result.get();
} catch (InterruptedException e) {
logger.error("Interrupted error", e);
} catch (ExecutionException e) {
logger.error("Thread Execution error", e);
} catch (Exception e) {
logger.error("Send Error", e);
}
if (entry == null) {
logger.error("Telemetry Send Error");
return;
}
logger.info("[Success] Task" + entry.getKey() + "-" + i);
}
Sender call():
@Override
public Map.Entry<Location, Data> call() throws InterruptedException {
Thread.sleep(5000);
return this.entry;
}
I see that each task is executed after the other. I want to execute all tasks in parallel and make it non-blocking.
Any idea what I'm missing? Isn't it what the executor service used to do?
答案1
得分: 0
在调用submit
后,你需要调用awaitTermination
。这样,你将为任务提供一些时间,直到达到你定义的超时时间或执行结束。
然后,你可以通过调用get
来检查未来的结果。
ExecutorService
API提供的另一个选项是调用invokeAll
,这是一个阻塞操作,触发所有任务。我个人更喜欢上面描述的第一种选项。
更新:另外,你没有显示ExecutorService
的配置,但我假设你正在分配多个线程给它。否则,无论你在submit
之后做什么,执行都将是顺序的。
英文:
After the invokation to submit
you need to invoke awaitTermination
. In that way, you will give some time for the task to get executed until a time out defined by you is reached or the execution ends.
Then, you should be able to check the future results by invoking get
.
Another option provided by the ExecutorService
API is to call invokeAll
which is a blocking operation that triggers all the tasks. I personally prefer the first option described above.
Update: Also, you didn´t show the ExecutorService
configuration but I assume that you are assigning more than one thread to it. Otherwise, the executions will be sequential no matter what you do after the submit
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论