[java] 미래와 약속의 차이점은 무엇입니까?

차이 무엇 FuturePromise?
둘 다 향후 결과를위한 자리 표시 자 역할을하지만 주요 차이점은 어디에 있습니까?



답변

이 토론 에 따르면 , Promise마침내 CompletableFutureJava 8에 포함되도록 요청되었으며 javadoc은 다음 과 같이 설명합니다.

명시 적으로 완료 될 수있는 (가치 및 상태 설정) 미래 완료시 트리거되는 종속 함수 및 조치를 지원하는 CompletionStage로 사용될 수 있습니다.

목록에 예가 있습니다.

f.then((s -> aStringFunction(s)).thenAsync(s -> ...);

최종 API는 약간 다르지만 비슷한 비동기 실행을 허용합니다.

CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);


답변

(지금까지 답변에 완전히 만족하지 않으므로 여기에 내 시도가 있습니다 …)

케빈 라이트의 의견 ( “약속을 할 수 있고 그것을 지키는 것은 당신에게 달려 있습니다. 다른 누군가가 당신에게 약속을하면 미래에 그것을 존중하는지 기다릴 수 있도록 기다려야합니다” )는 요약하지만, 일부는 설명이 유용 할 수 있습니다.

미래와 약속 은 매우 유사한 개념이지만, 미래는 아직 존재하지 않는 결과에 대한 읽기 전용 컨테이너이며 약속은 작성할 수 있지만 (보통 한 번만) 차이가 있습니다. 자바 8 CompletableFuture 와 구아바 SettableFuture가 자신의 값 ( “완료”)을 설정할 수 있기 때문에, 약속으로 생각하지만, 그들은 또한 미래의 인터페이스를 구현 할 수있다, 따라서 클라이언트에 대한 차이가 없다.

미래의 결과는 비동기 계산의 결과로 “다른 사람”에 의해 설정됩니다. 어떻게 참고 FutureTask 고전 미래가 – – 해야한다 주는, Callable 또는 Runnable를 사용하여 초기화 할 수는없는 인수 없음의 생성자가 없다, 그리고 미래와 FutureTask 모두 읽기 전용 외부에서 (FutureTask의 설정 방법은 보호)된다. 값은 내부에서 계산 한 결과로 설정됩니다.

다른 한편으로, 약속의 결과는 공개 세터 방법이 있기 때문에 언제라도 “귀하”(또는 사실상 누구에 의해)에 의해 설정 될 수 있습니다. CompletableFuture와 SettableFuture는 모두 작업없이 만들 수 있으며 언제든지 값을 설정할 수 있습니다. 클라이언트 코드에 약속을 보내고 나중에 원하는대로 이행하십시오.

CompletableFuture는 “순수한”약속이 아니며 FutureTask와 같은 작업으로 초기화 할 수 있으며 가장 유용한 기능은 처리 단계의 관련이없는 체인입니다.

또한 약속은 미래의 하위 유형일 필요는 없으며 동일한 객체 일 필요는 없습니다. 스칼라에서 미래 객체는 비동기 계산 또는 다른 Promise 객체에 의해 생성됩니다 . C ++에서는 상황이 비슷합니다. 프로 미스 오브젝트는 생산자가 사용하고 미래 오브젝트는 소비자가 사용합니다. 이 분리의 장점은 클라이언트가 미래의 가치를 설정할 수 없다는 것입니다.

SpringEJB 3.1 에는 모두 Scala / C ++ 약속과 비슷한 AsyncResult 클래스가 있습니다. AsyncResult는 Future를 구현하지만 이것이 실제 미래는 아닙니다. Spring / EJB의 비동기 메소드는 배경 마술을 통해 다른 읽기 전용 Future 객체를 반환하며이 두 번째 “실제”미래는 클라이언트가 결과에 액세스하는 데 사용할 수 있습니다.


답변

나는 이미 받아 들여진 대답이 있음을 알고 있지만 그럼에도 불구하고 내 2 센트를 추가하고 싶습니다.

TLDR : 미래와 약속은 비동기 작업의 두 가지 측면입니다 : 소비자 / 발신자생산자 / 구현 자 .

비동기 API 메소드 의 호출자Future 로서 계산 결과에 대한 핸들로 얻을 수 있습니다. 예를 들어 get()계산을 완료하고 결과를 검색 할 때까지 기다릴 수 있습니다 .

이제이 API 메소드가 실제로 어떻게 구현되는지 생각해보십시오. 구현 자는 Future즉시 반환해야합니다 . 그들은 계산이 완료 되 자마자 그 미래를 완성 할 책임이 있습니다 (파견 논리를 구현하고 있기 때문에 알게 될 것입니다 ;-)). 그들은 Promise/ CompletableFuture를 사용하여 다음 을 수행합니다. CompletableFuture즉시 구성하고 반환 complete(T result)하고 계산이 완료되면 호출 합니다.


답변

Promise가 무엇인지, 그리고 그 값을 읽을 수만있는 Future와는 반대로 언제라도 그 값을 설정할 수있는 방법에 대한 예를 들겠습니다.

엄마가 있고 돈을 요구한다고 가정 해 봅시다.

// Now , you trick your mom into creating you a promise of eventual
// donation, she gives you that promise object, but she is not really
// in rush to fulfill it yet:
Supplier<Integer> momsPurse = ()-> {

        try {
            Thread.sleep(1000);//mom is busy
        } catch (InterruptedException e) {
            ;
        }

        return 100;

    };


ExecutorService ex = Executors.newFixedThreadPool(10);

CompletableFuture<Integer> promise =
CompletableFuture.supplyAsync(momsPurse, ex);

// You are happy, you run to thank you your mom:
promise.thenAccept(u->System.out.println("Thank you mom for $" + u ));

// But your father interferes and generally aborts mom's plans and 
// completes the promise (sets its value!) with far lesser contribution,
// as fathers do, very resolutely, while mom is slowly opening her purse 
// (remember the Thread.sleep(...)) :
promise.complete(10); 

그 결과는 다음과 같습니다.

Thank you mom for $10

엄마의 약속이 만들어졌지만 “완료”이벤트를 기다렸습니다.

CompletableFuture<Integer> promise...

당신은 그녀의 약속을 받아들이고 당신의 엄마에게 감사하겠다는 계획을 발표하면서 그러한 행사를 만들었습니다.

promise.thenAccept...

이 순간 엄마는 지갑을 열기 시작했지만 …

아버지는 훨씬 빨리 간섭하여 엄마 대신 약속을 완수했습니다.

promise.complete(10);

내가 명시 적으로 작성한 유언 집행 인을 눈치 채 셨나요?

흥미롭게도, 기본 암시 적 executor를 대신 사용하고 (commonPool) 아버지가 집에 있지 않고 “느린 지갑”을 가진 엄마 만 있다면, 프로그램이 엄마보다 돈을 벌어야하는 것보다 오래 살면 약속이 완료됩니다. 지갑.

기본 실행자는 “데몬”처럼 작동하며 모든 약속이 이행되기를 기다리지 않습니다. 나는이 사실에 대한 좋은 설명을 찾지 못했습니다 …


답변

이 대답을 할 수 있습니다 확실하지하지만 만약 내가 다른 사람들이 당신이이 개념을 모두 두 개의 별도의 추상화를 필요로처럼 (의 하나가 그래서 보일 수 있습니다 사람을 말한 참조로 Future() 다른 단지 읽기 전용이다 Promise) …하지만 실제로는 필요하지 않습니다.

예를 들어 Javascript에서 약속이 어떻게 정의되는지 살펴보십시오.

https://promisesaplus.com/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

다음 then과 같은 방법을 사용하여 구성 가능성에 중점을 둡니다 .

asyncOp1()
.then(function(op1Result){
  // do something
  return asyncOp2();
})
.then(function(op2Result){
  // do something more
  return asyncOp3();
})
.then(function(op3Result){
  // do something even more
  return syncOp4(op3Result);
})
...
.then(function(result){
  console.log(result);
})
.catch(function(error){
  console.log(error);
})

비동기 계산을 동기식으로 보이게 만듭니다.

try {
  op1Result = syncOp1();
  // do something
  op1Result = syncOp2();
  // do something more
  op3Result = syncOp3();
  // do something even more
  syncOp4(op3Result);
  ...
  console.log(result);
} catch(error) {
  console.log(error);
}

꽤 멋지다. ( async-await 만큼 시원 하지는 않지만 async-await 는 상용구를 제거합니다 …. then (function (result) {…. ).

실제로 그들의 추상화는 약속 생성자로 꽤 좋습니다.

new Promise( function(resolve, reject) { /* do it */ } );

Promise성공적으로 완료하거나 오류와 함께 사용할 수있는 두 개의 콜백을 제공 할 수 있습니다 . 따라서 코드를 구성하는 코드 만 코드를 Promise완성 할 수 있으며 이미 생성 된 Promise객체 를받는 코드 는 읽기 전용보기를 갖습니다.

상속 상기 경우에 달성 될 수 결의거부 의 보호 방법이다.


답변

클라이언트 코드의 경우 Promise는 결과를 사용할 수있을 때 콜백을 관찰하거나 첨부하는 반면 Future는 결과를 기다렸다가 계속하는 것입니다. 이론적으로는 약속으로 할 수있는 일과 선물로 할 수있는 모든 것이 있지만 스타일 차이로 인해 다른 언어로 된 약속에 대한 결과 API는 체인을 더 쉽게 만듭니다.


답변

Future 인터페이스에는 set 메소드가없고 get 메소드 만 있으므로 읽기 전용입니다. CompletableFuture에 대해이 기사가 도움이 될 수 있습니다.
완성 할 수있는