我发现收集提交给IExecutorService的任务的结果涉及一些延迟。这只是在试图以期货的形式收集结果的情况下,通过使用从ExecutorService继承的提交(可调用任务)。我还发现,当您通过异步回调收集结果时性能良好。 考虑到期货也是异步的,我试图理解为什么在检索结果方面存在滞后。这是否与hazelcast的工作原理有关?
另外,如果我使用submit(可调用任务,ExecutionCallback回调),我应该期待什么样的行为?我是否应该随机选择一个成员来执行,有无负载平衡?
修改:使用一些示例代码更新问题。我将期货存储在集合中并稍后检索它。但是当主线程继续读取未来值时,我发现与异步回调相比有一个延迟。
final IExecutorService executorService = hz.getExecutorService("default");
List<Future<String>> list = Lists.newArrayList();
for (int i = 0; i < 100; i++) {
final Future<String> f = executorService.submit(new Echo(" " + i));
list.add(f);
}
System.out.println();
for (Future<String> f : list){
System.out.println(f.get());
}
而不是
final IExecutorService executorService = hz.getExecutorService("default");
final List<String> list = Lists.newArrayList();
final Stopwatch stopwatch = Stopwatch.createStarted();
for (int i = 0; i < 100; i++) {
executorService.submit(new Echo(" " + i), new ExecutionCallback<String>() {
@Override
public void onResponse(String response) {
System.out.println(response);
list.add(response);
if(list.size() == 100){
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println("time taken to complete is: "+millis);
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
答案 0 :(得分:3)
答案很难:)
当你在提交后立即执行future.get时,你不会给线程一个机会,但是它们会在很多时候阻塞。当你第一次提交一大堆并将期货存储在一个集合中时,我猜你会得到与异步执行类似的性能。这样,提交操作不会在完成时阻塞,并且工作线程也不会阻塞队列,因为队列充满了操作。所以你获得了更好的吞吐量。
我正在基于Java 8的CompleteableFuture开发基于Hazelcast的反应式API,因此您可以直接在未来注册回调。最终,带回调的提交将被删除。
我还在开发一个新的OperationService实现; Hazelcast的“引擎”负责实际执行操作。我正在玩各种优化,比如调用者运行优化,可以防止操作排队的所有常规开销。这也与期货非常紧密地结合在一起,我想从表现中挤出更多;特别是对于本地电话。
[编辑] 它只会随机选择群集中的成员。如果要进行负载平衡,则需要确定哪个成员是任务的最佳目标,然后使用
发送void submitToMember(Runnable task, Member member, ExecutionCallback callback);