Java 如何将延迟结果与可列出的未来列表相结合?
我有一个番石榴Java 如何将延迟结果与可列出的未来列表相结合?,java,spring-mvc,guava,future,Java,Spring Mvc,Guava,Future,我有一个番石榴ListenableFuture实例和SpringDeferredResult的列表。我想为列表中第一个成功的未来设置结果,或者如果超时尚未过期,则从所有未来获得成功的结果。以下是我的尝试: DeferredResult<String> foo() { DeferredResult<String> result = new DeferredResult<>(3000L); List<String> resps = n
ListenableFuture
实例和SpringDeferredResult
的列表。我想为列表中第一个成功的未来设置结果,或者如果超时尚未过期,则从所有未来获得成功的结果。以下是我的尝试:
DeferredResult<String> foo() {
DeferredResult<String> result = new DeferredResult<>(3000L);
List<String> resps = newArrayList();
List<ListenableFuture<String>> fList = ...
fList.forEach(f -> Futures.addCallback(f, new FutureCallback<String>() {
@Override
public void onSuccess(String resp) {
resps.add(resp);
}
@Override
public void onFailure(Throwable t) {
// NOP
}
}));
ListenableFuture<List<String>> f0 = Futures.successfulAsList(fList);
Futures.addCallback(f0, new FutureCallback<List<String>>() {
@Override
public void onSuccess(List<String> r) {
if (!result.hasResult()) {
result.
if (r != null) {
result.setResult(...);
}
}
}
@Override
public void onFailure(Throwable t) {
// NOP
}
});
return result;
}
DeferredResult foo(){
递延结果=新递延结果(3000L);
List resps=newArrayList();
列表fList=。。。
fList.forEach(f->Futures.addCallback(f,newfuturecallback()){
@凌驾
成功时的公共无效(字符串响应){
分别添加(分别);
}
@凌驾
失效时的公共无效(可丢弃的t){
//不
}
}));
ListenableFuture f0=Futures.successfulAsList(fList);
Futures.addCallback(f0,newfuturecallback(){
@凌驾
成功时公开作废(列表r){
如果(!result.hasResult()){
结果。
如果(r!=null){
result.setResult(…);
}
}
}
@凌驾
失效时的公共无效(可丢弃的t){
//不
}
});
返回结果;
}
我的代码不工作,因为它等待来自所有未来的结果,但我需要延迟结果超时的最快结果。如何修复它?延迟结果foo(){
DeferredResult<String> foo() {
DeferredResult<String> result = new DeferredResult<>(3000L);
List<ListenableFuture<String>> fList = ...
ExecutorService serializingExecutor = Executors.newSingleThreadExecutor();
fList.forEach(
f ->
Futures.addCallback(
f,
new FutureCallback<String>() {
@Override
public void onSuccess(String value) {
if (!result.hasResult()) {
result.setResult(value);
}
}
@Override
public void onFailure(Throwable throwable) {}
},
// To avoid race in the callback:
serializingExecutor));
return result;
}
递延结果=新递延结果(3000L);
列表fList=。。。
ExecutorService serializingExecutor=Executors.newSingleThreadExecutor();
弗利斯特·弗雷奇(
f->
期货公司(
F
新未来回调(){
@凌驾
成功时的公共void(字符串值){
如果(!result.hasResult()){
result.setResult(值);
}
}
@凌驾
失败时公共无效(可丢弃){
},
//要避免回调中的争用,请执行以下操作:
序列化执行器);
返回结果;
}
这将返回包装器对象,其中包含在超时之前成功完成的未来结果列表,并指示是否全部完成(allFinished
属性)
在处理代码中,您可以检查是否全部完成,并返回整个列表或仅返回第一项(如果以后没有完成,则无)
DeferredResult foo(){
递延结果=新递延结果(3000L);
ListingExecutorService executor=MoreExecutors.ListingDecorator(Executors.newFixedThreadPool(3));
List fList=IntStream.range(11000)
.mapToObj(i->executor.submit(()->String.valueOf(i)).collect(Collectors.toList());
List resps=Lists.newArrayListWithCapacity(fList.size());
对象锁=新对象();
fList.forEach(f->Futures.addCallback(f,newfuturecallback()){
@凌驾
成功时的公共无效(字符串响应){
已同步(锁定){
分别添加(分别);
result.setResult(新的ResultWrapper(
resps.size()==fList.size(),
不可变列表。副本(resps));
}
}
@凌驾
失效时的公共无效(可丢弃的t){
//不
}
}));
返回结果;
}
私有静态类ResultRapper{
私有布尔运算完成;
私人名单;
public ResultRapper(布尔allFinished,List){
this.allFinished=allFinished;
this.list=列表;
}
公共布尔值isAllFinished(){
返回所有已完成的;
}
公共列表getList(){
退货清单;
}
}
请解释这是做什么的。您是如何实现的?我想为列表中第一个成功的未来设置结果,或者如果超时尚未过期,则从所有未来获得成功的结果?不需要调用hasResult
<代码>设置结果如果已设置结果,则返回false
。
DeferredResult<ResultWrapper> foo() {
DeferredResult<ResultWrapper> result = new DeferredResult<>(3000L);
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(3));
List<ListenableFuture<String>> fList = IntStream.range(1, 1000)
.mapToObj(i -> executor.submit(() -> String.valueOf(i))).collect(Collectors.toList());
List<String> resps = Lists.newArrayListWithCapacity(fList.size());
Object lock = new Object();
fList.forEach(f -> Futures.addCallback(f, new FutureCallback<String>() {
@Override
public void onSuccess(String resp) {
synchronized (lock) {
resps.add(resp);
result.setResult(new ResultWrapper(
resps.size() == fList.size(),
ImmutableList.copyOf(resps)));
}
}
@Override
public void onFailure(Throwable t) {
// NOP
}
}));
return result;
}
private static class ResultWrapper {
private boolean allFinished;
private List<String> list;
public ResultWrapper(boolean allFinished, List<String> list) {
this.allFinished = allFinished;
this.list = list;
}
public boolean isAllFinished() {
return allFinished;
}
public List<String> getList() {
return list;
}
}