Java 8 completable future可并行执行方法
我有3个方法需要并行运行,因为它们彼此独立,并在最后合并每个方法的结果,并将其作为响应发送。我还需要处理异常 在不同的帖子中,我找到了下面的代码并进行了相应的修改Java 8 completable future可并行执行方法,java,java-8,completable-future,Java,Java 8,Completable Future,我有3个方法需要并行运行,因为它们彼此独立,并在最后合并每个方法的结果,并将其作为响应发送。我还需要处理异常 在不同的帖子中,我找到了下面的代码并进行了相应的修改 public Response getResponse() { Response resultClass = new Response(); try { CompletableFuture<Optional<ClassA>> classAFuture = Completab
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(){
Response resultClass=新响应();
试一试{
完整的未来类别未来
=CompletableFuture.SupplySync(()->service.getClassA());
完全未来类未来
=CompletableFuture.SupplySync(()->{
试一试{
return service.getClassB();
}
捕获(例外e){
抛出新的CompletionException(e);
}
});
完全未来类未来
=CompletableFuture.SupplySync(()->{
试一试{
return service.getClassC();
}捕获(例外e){
抛出新的CompletionException(e);
}
});
完全的未来反应未来=
CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
.然后应用同步(虚拟->{
if(classAFuture.join().isPresent()){
ClassA ClassA=classAFuture.join();
setClassB(classBFuture.join());
classA.setClassC(classCFuture.join());
response.setClassA(classA)
}
返回响应;
});
responseFuture.join();
}捕获(完成执行e){
投掷e;
}
返回响应;
}
上述方法是否应该并行运行?我发现这需要更多的时间,我想确保我做得正确。如果要并行运行方法,应该使用ExecutorService。请尝试类似的方法:
ExecutorService myExecutor = Executors.newFixedThreadPool(3);
List<Future<Object>> futures = myExecutor.invokeAll(
Arrays.asList(
() -> service.getClassA(),
() -> service.getClassB(),
() -> service.getClassC(),
)
);
myExecutor.shutdown();
ExecutorService myExecutor=Executors.newFixedThreadPool(3);
列表期货=myExecutor.invokeAll(
Arrays.asList(
()->service.getClassA(),
()->service.getClassB(),
()->service.getClassC(),
)
);
myExecutor.shutdown();
如果要并行运行方法,应使用ExecutorService。请尝试以下操作:
ExecutorService myExecutor = Executors.newFixedThreadPool(3);
List<Future<Object>> futures = myExecutor.invokeAll(
Arrays.asList(
() -> service.getClassA(),
() -> service.getClassB(),
() -> service.getClassC(),
)
);
myExecutor.shutdown();
ExecutorService myExecutor=Executors.newFixedThreadPool(3);
列表期货=myExecutor.invokeAll(
Arrays.asList(
()->service.getClassA(),
()->service.getClassB(),
()->service.getClassC(),
)
);
myExecutor.shutdown();
这个想法是正确的,但这一切都可以用更少的代码来完成:
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;
}
}
}
public Response getResponse(){
CompletableFuture classAFuture=CompletableFuture.SupplySync(()->service.getClassA());
CompletableFuture-classBFuture=CompletableFuture.supplyAsync(()->service.getClassB());
CompletableFuture类未来=CompletableFuture.SupplySync(()->service.getClassC());
试一试{
返回CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
。然后应用(()->{
响应=新响应();
可选的maybeA=classAFuture.get();
if(maybeA.isPresent()){
ClassA ClassA=maybeA.get();
setClassB(classBFuture.get());
setClassC(classCFuture.get());
回复:setClassA(classA);
}
返回响应;
}).get();
}catch(ExecutionException){//通常,java并发框架本身会将异常包装为ExecutionException
可丢弃的原因=e.getCause();
如果(原因!=null){
抛出原因;
}否则{
投掷e;
}
}
}
主要事项:
CompletionException
然后applyasync
。除非您想非常具体地说明要使用的线程类型,否则使用然后apply
是一样的。有关详细信息,请查看此项join()
任何操作。当CompletableFuture.all
完成时,您可以非常确定所有提供的作业都已完成,然后调用get()
将只返回值至于你能确定作业A、B和C将并行运行吗?是和否。如果有足够的系统资源并行运行它们,它将并行运行。你已经尽了最大努力让它们并行运行。也许在某个时候你还想提供自定义线程池以获得更多控制,但这是另一天的主题。这个想法是正确的,但这一切都可以用更少的代码来完成:
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;
}
}
}
public Response getResponse(){
CompletableFuture classAFuture=CompletableFuture.SupplySync(()->service.getClassA());
CompletableFuture-classBFuture=CompletableFuture.supplyAsync(()->service.getClassB());
CompletableFuture类未来=CompletableFuture.SupplySync(()->service.getClassC());
试一试{
返回CompletableFuture.allOf(classAFuture,classBFuture,classCFuture)
。然后应用(()->{
响应=新响应();
可选的maybeA=classAFuture.get();
if(maybeA.isPresent()){
ClassA ClassA=maybeA.get();
setClassB(classBFuture.get());
setClassC(classCFuture.get());
回复:setClassA(classA);
}
返回响应;
}).get();
}catch(ExecutionException){//通常,java并发框架本身会将异常包装为ExecutionException
可丢弃的原因=e.getCause();
如果(原因!=null){
抛出原因;
}否则{
投掷e;
}
}
}
主要事项:
CompletionException