java 8 completablefuture在for循环中,强制异步同步或类似于链
目前,我有一个要求,使异步任务同步在completablefuture。任务A和任务B可以在将来完成。任务B在任务A完成时运行。这只适用于一次。假设我让它在foor循环中运行,显然它将创建n个异步调用来实现结果。因此,我得到的o/p如下所示java 8 completablefuture在for循环中,强制异步同步或类似于链,java,asynchronous,java-8,completable-future,Java,Asynchronous,Java 8,Completable Future,目前,我有一个要求,使异步任务同步在completablefuture。任务A和任务B可以在将来完成。任务B在任务A完成时运行。这只适用于一次。假设我让它在foor循环中运行,显然它将创建n个异步调用来实现结果。因此,我得到的o/p如下所示 A B A A B B A B A A A 我想达到这样的目标 A B A B A B A B 这是密码 package com.demo.completable.combine; import javax.xml.stream.Location; i
A
B
A
A
B
B
A
B
A
A
A
我想达到这样的目标
A
B
A
B
A
B
A
B
这是密码
package com.demo.completable.combine;
import javax.xml.stream.Location;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class ThenCompose {
synchronized CompletableFuture<User> getUserDetails(String name) {
return CompletableFuture.supplyAsync(() -> {
return UserService.getUser(name);
});
}
synchronized CompletableFuture<Double> getRating(User user) {
return CompletableFuture.supplyAsync(() -> {
return CreditRating.getCreditRating(user);
});
}
synchronized CompletableFuture<String> getResult(Double rating) {
return CompletableFuture.supplyAsync(()-> {
return "welcome world";
});
}
public void main() throws InterruptedException, ExecutionException {
ThenCompose cc = new ThenCompose();
// then apply
CompletableFuture<CompletableFuture<Double>> result = cc.getUserDetails("kumaran").thenApply(user -> {
return cc.getRating(user);
});
// then compose
for (int i = 1; i <= 15; i++) {
CompletableFuture<Double> taskA = cc.getUserDetails("mike").thenCompose(user -> {
System.out.println("Task A --- " +Thread.currentThread().getName() + "--" + LocalTime.now());
return cc.getRating(user);
});
CompletableFuture<String> fileLocation =
taskA.thenCompose(ts -> {
System.out.println("Task B --- " +Thread.currentThread().getName() + "--- " + LocalTime.now());
return getResult(ts);
});
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThenCompose tc = new ThenCompose();
tc.main();
}
}
package com.demo.completable.combine;
导入javax.xml.stream.Location;
导入java.time.LocalDateTime;
导入java.time.LocalTime;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.*;
公共类{
已同步CompletableFuture getUserDetails(字符串名称){
返回CompletableFuture.SupplySync(()->{
返回UserService.getUser(名称);
});
}
已同步CompletableFuture getRating(用户){
返回CompletableFuture.SupplySync(()->{
返回CreditRating.getCreditRating(用户);
});
}
已同步CompletableFuture getResult(双重评级){
返回CompletableFuture.SupplySync(()->{
回归“欢迎世界”;
});
}
public void main()引发InterruptedException,ExecutionException{
thencomose cc=new thencomose();
//然后申请
CompletableFuture result=cc.getUserDetails(“kumaran”)。然后应用(用户->{
返回cc.getRating(用户);
});
//然后写
对于(int i=1;i{
System.out.println(“任务A----”+Thread.currentThread().getName()+”--“+LocalTime.now());
返回cc.getRating(用户);
});
可完成的未来文件位置=
任务A.然后撰写(ts->{
System.out.println(“任务B----”+Thread.currentThread().getName()+”--“+LocalTime.now());
返回getResult(ts);
});
}
}
公共静态void main(字符串[]args)引发ExecutionException、InterruptedException{
ThenCompose tc=新建ThenCompose();
tc.main();
}
}
把join和get放在一起会起作用,但我不应该同时使用join和get。请建议解决方案。请尝试下面的代码,该代码按顺序执行任务。它会给你预期的结果
static Integer methA(int seq) {
System.out.println("A-"+seq);
return seq;
}
static Integer methB(int seq) {
System.out.println("B-"+seq);
return seq;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
System.out.println("Main started:");
CompletableFuture<Integer> ft = null;
for(int a=0;a<15;a++) {
final int seq = a;
if(ft==null) {
ft = CompletableFuture.supplyAsync(()->methA(seq))
.thenApply(s->methB(s));
}else {
ft.thenApply((s)->methA(seq))
.thenApply(s->methB(s));
}
}
ft.thenAccept(s->System.out.println("Thread completed..."+s));
System.out.println("Main ended:");
}
静态整数methA(int-seq){
系统输出打印项次(“A-”+序号);
返回顺序;
}
静态整数方法(整数顺序){
系统输出打印项次(“B-”+序号);
返回顺序;
}
公共静态void main(字符串[]args)引发InterruptedException、ExecutionException{
System.out.println(“主启动:”;
CompletableFuture ft=null;
对于(INTA=0;amethA(seq))
。然后应用->方法;
}否则{
ft.thenApply((s)->甲烷(seq))
。然后应用->方法;
}
}
ft.tenaccept(s->System.out.println(“线程完成…”+s));
System.out.println(“主端:”);
}
我不认为您被迫使用get with join。您可以尝试使用连接使用accept()。您可以参考它在何处使用CompletableFuture with join。虽然它使用get(),但您可以尝试用thenacept()替换它。是的,我也使用了thenacept()。这没什么区别。我想说的是,我在循环中运行上述代码3次,以命中一个api。我想表现得如下`线程1-请求1,响应1-线程2-请求2,响应2-线程3-请求3,回复3`但我现在得到的是如下所示`线程1-请求1线程2-请求2线程3-请求3线程1-响应1线程2-响应2线程3-响应3`谢谢@Ashok Prajapati,但由于您使用了join,它可以工作。但我这里的用例不是使用连接。我正在寻找某种连锁式的实现<代码>用于(int i=0;i@LearningPath,我已经更新了我的答案,并且在没有加入或获取的情况下解决了这个问题。我通过在同一个可完成的未来对象上创建一个链来解决这个问题。希望它能够解决您的问题。感谢@Ashok Prajapati。我正在寻找相同的答案。我将尝试在我的用例中实现它。