수색…


소개

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!
    });
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow