+1 امتیاز
قبل در برنامه نویسی توسط (1.1هزار امتیاز)

کلاس CompletableFuture متدی با نام join دارد، کاربرد این متد چیست؟

1 پاسخ

+1 امتیاز
قبل توسط (1.1هزار امتیاز)
انتخاب شده قبل توسط
 
بهترین پاسخ

کلاس CompletableFuture در جاوا ۸ معرفی شده و متد join آن شبیه متد get در کلاس Future است با این تفاوت که هیچ checked exception ی پرتاب نمی کند. کاربرد عملی متد join زمانی است که شما تعدادی شئ از نوع CompletableFuture در یک stream دارید که می خواهید پس از اتمام تمام آنها، نتایج با هم join شوند و در قالب یک stream از جنس value درون CompletableFuture تبدیل شود. در مثال زیر متد getPrice از کلاس Shop نوع Future بر می گرداند و برای اینکه سیستم block نشود ابتدا تمام قیمت ها به نوع CompletableFuture تبدیل می شوند و در نهایت نتایج آنها با متد join در قالب یک لیست از String جمع می شود.

        List<Shop> shops; //= ...        

        List<CompletableFuture<String>> priceFutures =
                shops.stream()
                        .map(shop -> CompletableFuture.supplyAsync(
                                () -> shop.getName() + shop.getPrice(product),executor))
                        .collect(toList());

        return priceFutures.stream().map(CompletableFuture::join).collect(toList());
قبل توسط (112 امتیاز)
این کد کاملا non-blocking نیست و علی رغم اینکه قیمت ها به طور موازی محاسبه میشه اما خط آخر به هر حال blocking هست (به خاطر فراخوانی join)

توصیه میشه که متد join بعد از آماده شدن future فراخوانی بشه.
مثال از تبدیل لیستی از future ها به future ای از لیست:

public static <T> CompletionStage<List<T>> allAsList(List<? extends CompletionStage<T>> stages) {
    CompletableFuture[] futures = stages.stream()
            .map(CompletionStage::toCompletableFuture)
            .toArray(CompletableFuture[]::new);
    return CompletableFuture.allOf(futures)
            .thenApply(v -> stages.stream()
                    .map(stage -> stage.toCompletableFuture().join())
                    .collect(Collectors.toList()));
}

...


CompletionStage<List<String>> pricesF = allAsList(priceFutures);
pricesF.thenAccept(prices -> prices.forEach(System.out::println));
قبل توسط (1.1هزار امتیاز)
بله درسته، اصلا سوال درباره Non-blocking نیست. شما درست میگید، join و get باعث بلاک شدن می شوند.

سوالات مشابه

+2 امتیاز
1 پاسخ 789 بازدید
0 امتیاز
3 پاسخ 929 بازدید
0 امتیاز
1 پاسخ 428 بازدید
0 امتیاز
0 پاسخ 320 بازدید
+2 امتیاز
2 پاسخ 1.1هزار بازدید
0 امتیاز
1 پاسخ 393 بازدید
0 امتیاز
1 پاسخ 473 بازدید
+1 امتیاز
1 پاسخ 197 بازدید
سوال شده 2 سال قبل در برنامه نویسی توسط masoud shahhosseini_ (45 امتیاز)
...