我有3种方法需要并行运行,因为它们彼此独立,并在最后合并每种方法的结果,并将其作为响应发送。我还需要处理异常。
在不同的帖子中,我找到了下面的代码并进行了相应的修改。
public Response getResponse() {
Response resultClass = new Response();
try {
CompletableFuture<Optional<ClassA>> classAFuture
= CompletableFuture.supplyAsync(() -> service.getClassA() );
CompletableFuture<ClassB> classBFuture
= CompletableFuture.supplyAsync(() -> {
try {
return service.getClassB();
}
catch (Exception e) {
throw new CompletionException(e);
}
});
CompletableFuture<ClassC> classCFuture
= CompletableFuture.supplyAsync(() -> {
try {
return service.getClassC();
} catch (Exception e) {
throw new CompletionException(e);
}
});
CompletableFuture<Response> responseFuture =
CompletableFuture.allOf(classAFuture, classBFuture, classCFuture)
.thenApplyAsync(dummy -> {
if (classAFuture.join().isPresent() {
ClassA classA = classAFuture.join();
classA.setClassB(classBFuture.join());
classA.setClassC(classCFuture.join());
response.setClassA(classA)
}
return response;
});
responseFuture.join();
} catch (CompletionExecution e) {
throw e;
}
return response;
}
上述各项是否应正确并行运行?我知道这需要更多的时间,我想确保我做对了。
这个想法是正确的,但这一切都可以用更少的代码来完成:
public Response getResponse() {
CompletableFuture<Optional<ClassA>> classAFuture = CompletableFuture.supplyAsync(() -> service.getClassA());
CompletableFuture<ClassB> classBFuture = CompletableFuture.supplyAsync(() -> service.getClassB());
CompletableFuture<ClassC> classCFuture = CompletableFuture.supplyAsync(() -> service.getClassC());
try {
return CompletableFuture.allOf(classAFuture, classBFuture, classCFuture)
.thenApply(() -> {
Response response = new Response();
Optional<ClassA> maybeA = classAFuture.get();
if (maybeA.isPresent()) {
ClassA classA = maybeA.get();
classA.setClassB(classBFuture.get());
classA.setClassC(classCFuture.get());
response.setClassA(classA);
}
return response;
}).get();
} catch (ExecutionException e) { // Ususally the exception is wrapped to ExecutionException by java concurrency framework itself
Throwable cause = e.getCause();
if (cause != null) {
throw cause;
} else {
throw e;
}
}
}
主要事情:
CompletionException
。thenApplyAsync
。只需thenApply
是一回事,除非您想非常具体地说明要使用的线程类型。检查此项以获取更多信息https://stackoverflow.com/a/47489654/3020903connect()
任何东西。当CompletableFuture.all
完成时,您可以非常确定所有提供的作业都已完成,然后调用get()
将只返回值。至于你能保证作业A、B和C将并行运行吗。是和否。如果有足够的系统资源并行运行,它将并行运行。你已经尽力要求他们并行运行。也许在某个时候,您还希望提供自定义线程池以获得更多控制,但这是另一天的主题。
如果您想并行运行方法,您应该使用ExecutorService。试试这样的方法:
ExecutorService myExecutor = Executors.newFixedThreadPool(3);
List<Future<Object>> futures = myExecutor.invokeAll(
Arrays.asList(
() -> service.getClassA(),
() -> service.getClassB(),
() -> service.getClassC(),
)
);
myExecutor.shutdown();
我编写了两个功能文件,每个功能文件打开不同的浏览器URL,例如一个是open google。com和secnd一个开放的亚马逊。但事实并非如此。 两个浏览器都打开了谷歌。通用域名格式。此外,它不能与浏览器交互,任何编码到浏览器的操作都不会执行。此外,关闭第一个浏览器会导致第二个浏览器出现空指针异常。 cucumber版本6我从AbstractCucumberTesNG继承开始。然后我创建登录。功能
我试图理解java中完整期货的非阻塞回调性质 有了上面的代码,我总是看到下面看到的输出 线程名称ForkJoinPool.common池工人-1 thenApply Thread name main thenApply Thread name main thenAcceptThread name main Thread name main 这个顺序似乎建议主线程等待所有Futures线程的执行。
我有一个关于Java流和链式可完成期货如何执行的问题。 我的问题是:如果我运行下面的代码,调用,列表中有10个项目需要大约11秒才能完成(列表中的项目数加1)。这是因为我有两个线程并行工作:第一个执行操作,一旦完成,第二个执行操作,第一个开始处理列表中的下一个项目。 如果我注释掉第36行(),那么方法需要大约20秒才能完成。Thread不平行运行;对于列表中的每个项目,操作完成,然后在处理列表中的
在下面的代码中,我试图理解java-8中提供的可选的概念。我创建了下面的例子来掌握orElse()背后的原理。执行代码后,defaultmethod()的主体被执行,并返回 对象y。log语句按照我的预期打印了正确的数据。 问题是,为什么defaultMethod()中的所有日志都没有打印??引入is-orElse()仅返回值,而不执行所提供方法的整个主体。? 代码: 日志:
我有一个viewmodel,它对API执行不同的请求,我现在是这样调用我的API的 这种方法的问题是,我需要等待每一个完成来启动另一个,在我对repo(都是挂起函数)执行此调用后,我通知livedata,但这需要一些时间(4-5秒),并且我希望同时执行所有调用,并在通知我的livedata之前一次捕获它们 我在找像这样的东西 我希望使用Async-Await而不是作业
我用reactiveX Zip做了一些实验,我注意到我在zip中定义的可观察性是一个接一个地执行的。我认为zip的好处是,zip中定义的每一个可观察到的线程都是由一个线程执行的,所以所有这些线程都是并行执行的。有什么方法能达到我想要的吗?。这是我的zip例子