Java Language
완료 할 수있는 미래
수색…
소개
CompletableFuture는 Java SE 8에서 Future 인터페이스를 구현하는 Java SE 8에 추가 된 클래스입니다. Future 인터페이스를 지원하는 것 외에도 미래가 완료 될 때 비동기 콜백을 허용하는 많은 메소드가 추가되었습니다.
차단 방법을 비동기식으로 변환
다음 방법은 웹 페이지를 검색하고 텍스트 길이를 계산하기 위해 연결에 따라 1-2 초 정도 걸립니다. 스레드가 호출 할 때마다 해당 기간 동안 차단됩니다. 또한 나중에 유용하게 사용할 수있는 예외를 다시 발생시킵니다.
public static long blockingGetWebPageLength(String urlString) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(new URL(urlString).openConnection().getInputStream()))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString().length();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
이렇게하면 블로킹 메서드 호출을 다른 스레드로 이동하여 즉시 반환 할 메서드로 변환됩니다. 기본적으로 supplyAsync 메소드는 공급자를 공통 풀에서 실행합니다. 블로킹 방법의 경우 이것은 선택적 서비스 매개 변수를 추가 한 이유 때문에 그 풀의 스레드가 소모 될 수 있으므로 좋지 않습니다.
static private ExecutorService service = Executors.newCachedThreadPool();
static public CompletableFuture<Long> asyncGetWebPageLength(String url) {
return CompletableFuture.supplyAsync(() -> blockingGetWebPageLength(url), service);
}
비동기 방식으로 함수를 사용하려면 thenAccept와 같이 완료 될 때 공급자의 결과로 호출 될 lamda를 허용하는 메소드를 사용해야합니다. 또한 예외적으로 사용하거나 발생한 예외를 기록하는 메서드를 처리하는 것이 중요합니다.
public static void main(String[] args) {
asyncGetWebPageLength("https://stackoverflow.com/")
.thenAccept(l -> {
System.out.println("Stack Overflow returned " + l);
})
.exceptionally((Throwable throwable) -> {
Logger.getLogger("myclass").log(Level.SEVERE, "", throwable);
return null;
});
}
CompletableFuture의 간단한 예제
아래 예제에서 calculateShippingPrice
메서드는 약간의 처리 시간이 소요되는 운송 비용을 계산합니다. 실제 예를 들어, 이것은 제품의 무게와 운송 방법에 따라 가격을 반환하는 다른 서버에 문의하는 것입니다.
CompletableFuture
를 통해 비동기식으로이를 모델링 CompletableFuture
메소드에서 다른 작업을 계속할 수 있습니다 (즉, 패키징 비용 계산).
public static void main(String[] args) {
int price = 15; // Let's keep it simple and work with whole number prices here
int weightInGrams = 900;
calculateShippingPrice(weightInGrams) // Here, we get the future
.thenAccept(shippingPrice -> { // And then immediately work on it!
// This fluent style is very useful for keeping it concise
System.out.println("Your total price is: " + (price + shippingPrice));
});
System.out.println("Please stand by. We are calculating your total price.");
}
public static CompletableFuture<Integer> calculateShippingPrice(int weightInGrams) {
return CompletableFuture.supplyAsync(() -> {
// supplyAsync is a factory method that turns a given
// Supplier<U> into a CompletableFuture<U>
// Let's just say each 200 grams is a new dollar on your shipping costs
int shippingCosts = weightInGrams / 200;
try {
Thread.sleep(2000L); // Now let's simulate some waiting time...
} catch(InterruptedException e) { /* We can safely ignore that */ }
return shippingCosts; // And send the costs back!
});
}