问题描述
import java.util.ArrayList;
import java.util.concurrent.CompletionStage;
import play.libs.concurrent.HttpExecutionContext;
import play.libs.ws.WSClient;
import play.libs.ws.WSRequest;
import play.libs.ws.WSResponse;
class CustomerDetailedData {
private String id;
private String role;
private String customerData;
}
class CustomrestClient {
private final WSClient ws;
private final HttpExecutionContext httpExecutionContext;
@javax.inject.Inject
public CustomrestClient(final WSClient ws,final HttpExecutionContext httpExecutionContext) {
this.ws = ws;
this.httpExecutionContext = httpExecutionContext;
}
public CompletionStage<RestResponse> get(final RestMessage restMessage) {
return ws.url(restMessage).get()
.thenApplyAsync(wsResponse -> {
return new RestResponse().setMsgBody(Json.parse(wsResponse.getBody()));
},httpExecutionContext.current());
}
}
public class CompletionStagesExample {
@Inject
private CustomrestClient customrestClient;
public static CompletionStage<CustomerDetailedData > getData(String url,String role,String id) {
return customrestClient.get(new RestMessage(url,role,id))
.thenApply(restResponse -> {
CustomerDetailedData customerData = convertToCustomerData(restResponse);
//here the role arg does not match response received by the get method
//(we got here response for roleC,but role argument of getData method has "roleB" value on the current step)
customerData.setRole(role);
return customerData;
});
}
public static void main(String[] args) {
final List<CompletableFuture<CustomerDetailedData>> futures = new ArrayList<>();
futures.add(getData("url for role A","RoleA","123123a").toCompletableFuture());
futures.add(getData("url for role B","RoleB","123123b").toCompletableFuture());
futures.add(getData("url for role C","RoleC","123123c").toCompletableFuture());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(aVoid -> {
final List<CustomerDetailedData> detailList = new ArrayList<>();
futures.stream()
.map(CompletableFuture::join)
.forEach(System.out::println);
});
}
}
输出看起来像这样(每次都可能不同):
[id = "123123a",role = "roleB",customerData = "角色 A 的一些数据 服务器返回"],[id = "123123b",role = "roleC",customerData = "服务器返回的角色 B 的一些数据"],[id = "123123c",role = "roleA",customerData = "服务器返回的角色 C 的一些数据"]
预期结果:
[id = "123123a",role = "roleA",role = "roleC",customerData = "服务器返回的角色 C 的一些数据"]
我建议 thenApply 主体中的 getData 方法中的角色混乱(与 id 不匹配),因为 thenApply 访问了 getData 方法参数的错误示例(它们正在更改顺序,因为 thenApply 在 WSRequest 返回的另一个线程中执行)。
有谁知道 Java 是否保证放置在 thenApply 中的代码始终可以访问方法参数的正确示例(在我的例子中是 getData 方法的参数)?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)