Java Future를 CompletableFuture로 전환
Java 8 CompletableFuture
은 구성 가능한 미래의 새로운 구현 인을 도입했습니다 (thenXxx 메소드 여러 개 포함). 독점적으로 사용하고 싶지만 사용하려는 많은 라이브러리는 구성 할 수없는 Future
인스턴스 만 반환 합니다.
반환 된 Future
인스턴스를 내부에 래핑하여 CompleteableFuture
구성 할 수있는 방법이 있습니까?
마음에 들지 않을 것입니다. 다음 메서드는를 a Future<T>
로 변환 합니다 CompletableFuture<T>
.
public static <T> CompletableFuture<T> makeCompletableFuture(Future<T> future) {
return CompletableFuture.supplyAsync(() -> {
try {
return future.get();
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
});
}
분명히이 접근 방식의 문제는 각 미래 에 대해 미래 의 결과를 기다리도록 차단 됩니다. 어떤 경우에는 더 잘할 수 있습니다. 그러나 일반적으로 Future 의 결과를 적극적으로 기다리지 않고서는 해결되지 않습니다 .
미래의 경우 스타일 추가 사용 방법도 제공하는 추가 추가 차단없이 CompletableFuture를 완료하는 경우를 사용할 수 있습니다. 이렇게 :
AsynchronousFileChannel open = AsynchronousFileChannel.open(Paths.get("/some/file"));
// ...
CompletableFuture<ByteBuffer> completableFuture = new CompletableFuture<ByteBuffer>();
open.read(buffer, position, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
completableFuture.complete(buffer);
}
@Override
public void failed(Throwable exc, Void attachment) {
completableFuture.completeExceptionally(exc);
}
});
completableFuture.thenApply(...)
하나의 유일한 방법은 모든 검사 를 해결하는 유일한 방법은 모든 Future.isDone()
검사를 단일에 배치 한 다음 Future가 얻을 수있을 때마다 완료를 호출 하는 폴링 루프를 사용하는 것 입니다.
나는 대답 의 간단한 방법보다 나은 것을 시도 하는 작은 미래 프로젝트를 발표했습니다 .
주요 아이디어는 내부의 모든 Futures 상태를 확인하기 위해 단 하나의 노래 (물론 오르간 루프가 아닌)를 사용하는 것입니다. 이것은 Future-> CompletableFuture 변환에 대해 풀에서 방지하는 것을 차단하는 것을 도움이됩니다.
사용 예 :
Future oldFuture = ...;
CompletableFuture profit = Futurity.shift(oldFuture);
암시 :
http://www.thedevpiece.com/converting-old-java-future-to-completablefuture/
그러나 기본적으로 :
public class CompletablePromiseContext {
private static final ScheduledExecutorService SERVICE = Executors.newSingleThreadScheduledExecutor();
public static void schedule(Runnable r) {
SERVICE.schedule(r, 1, TimeUnit.MILLISECONDS);
}
}
그리고 CompletablePromise :
public class CompletablePromise<V> extends CompletableFuture<V> {
private Future<V> future;
public CompletablePromise(Future<V> future) {
this.future = future;
CompletablePromiseContext.schedule(this::tryToComplete);
}
private void tryToComplete() {
if (future.isDone()) {
try {
complete(future.get());
} catch (InterruptedException e) {
completeExceptionally(e);
} catch (ExecutionException e) {
completeExceptionally(e.getCause());
}
return;
}
if (future.isCancelled()) {
cancel(true);
return;
}
CompletablePromiseContext.schedule(this::tryToComplete);
}
}
예 :
public class Main {
public static void main(String[] args) {
final ExecutorService service = Executors.newSingleThreadExecutor();
final Future<String> stringFuture = service.submit(() -> "success");
final CompletableFuture<String> completableFuture = new CompletablePromise<>(stringFuture);
completableFuture.whenComplete((result, failure) -> {
System.out.println(result);
});
}
}
다른 옵션을 제안하겠습니다. https://github.com/vsilaev/java-async-await/tree/master/com.farata.lang.async.examples/src/main/java/com/farata / 병발 사정
간단히 말해서 아이디어는 다음과 가능합니다.
CompletableTask<V>
인터페이스 소개 -CompletionStage<V>
+ 의 결합RunnableFuture<V>
- 워프
ExecutorService
으로 돌아 가기CompletableTask
에서submit(...)
방법 (대신Future<V>
) - 완료되었습니다. 실행 가능하고 구성 가능한 선물이 있습니다.
구현 대안 CompletionStage 구현을 사용 (유료주의, CompletionStage 오히려 CompletableFuture 이상) :
용법:
J8ExecutorService exec = J8Executors.newCachedThreadPool();
CompletionStage<String> = exec
.submit( someCallableA )
.thenCombineAsync( exec.submit(someCallableB), (a, b) -> a + " " + b)
.thenCombine( exec.submit(someCallableC), (ab, b) -> ab + " " + c);
참고 URL : https://stackoverflow.com/questions/23301598/transform-java-future-into-a-completablefuture
'ProgramingTip' 카테고리의 다른 글
일부 사람들에게만 "네이티브 서체를 만들 수 없습니다" (0) | 2020.10.20 |
---|---|
javadoc을 private 필드에 연결하는 방법은 무엇입니까? (0) | 2020.10.19 |
SignalR 2.0 .NET 클라이언트를 서버 허브에 다시 연결하는 모범 사례 (0) | 2020.10.19 |
왜 \ 0을 C에서 char 배열의 첫 번째 요소로 정의하고 있습니까? (0) | 2020.10.19 |
씨 # /. NET의 네임 스페이스 전용 클래스 가시성? (0) | 2020.10.19 |