पूरा करने योग्य सम्मिलित हों बनाम प्राप्त करें


95

बीच क्या अंतर है CompletableFuture.get()और CompletableFuture.join()?

नीचे मेरा कोड है:

List<String> process() {

    List<String> messages = Arrays.asList("Msg1", "Msg2", "Msg3", "Msg4", "Msg5", "Msg6", "Msg7", "Msg8", "Msg9",
            "Msg10", "Msg11", "Msg12");
    MessageService messageService = new MessageService();
    ExecutorService executor = Executors.newFixedThreadPool(4);

    List<String> mapResult = new ArrayList<>();

    CompletableFuture<?>[] fanoutRequestList = new CompletableFuture[messages.size()];
    int count = 0;
    for (String msg : messages) {
        CompletableFuture<?> future = CompletableFuture
                .supplyAsync(() -> messageService.sendNotification(msg), executor).exceptionally(ex -> "Error")
                .thenAccept(mapResult::add);

        fanoutRequestList[count++] = future;
    }

    try {
        CompletableFuture.allOf(fanoutRequestList).get();
      //CompletableFuture.allOf(fanoutRequestList).join();
    } catch (InterruptedException | ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return mapResult.stream().filter(s -> !s.equalsIgnoreCase("Error")).collect(Collectors.toList());
}

मैंने दोनों विधियों के साथ प्रयास किया है लेकिन मुझे परिणाम में कोई अंतर नहीं दिखाई देता है।


11
get()आपको अपवादों को पकड़ने की आवश्यकता है। जब आप से बदलने के अंतर नोटिस चाहिए get()करने के लिए join(), जैसा कि आप तुरंत कह रही है कि न तो एक संकलक त्रुटि प्राप्त होगी InterruptedExceptionऔर न ही ExecutionExceptionमें फेंक दिया जाता है tryब्लॉक।
होल्गर

5
@ होली-जावा: join()बाधित नहीं हो सकता।
होल्गर

@ होल्गर हां, सर। मैंने पाया कि मैं इस कार्य को बाधित नहीं कर सकता।
होली-जावा

9
अच्छी तरह से getमौजूद है, क्योंकि इंटरफ़ेस को CompletableFutureलागू करता Futureहै जो इसे अनिवार्य करता है। join()सबसे अधिक संभावना पेश की गई है, वायदा का संयोजन करते समय लंबोदर अभिव्यक्तियों में जाँच किए गए अपवादों को पकड़ने की आवश्यकता से बचने के लिए। अन्य सभी उपयोग मामलों में, आप जो भी पसंद करते हैं, उसका उपयोग करने के लिए स्वतंत्र महसूस करें।
होल्गर

1
क्या यह वास्तव में जुड़ने या धागे पर दोनों ब्लॉक के रूप में उपयोग करने के लिए समझ में आता है। इसके बजाय हम अतुल्यकालिक कार्यों की एक श्रृंखला बनाने के लिए अन्य रचना विधियों का उपयोग करके इस अतुल्यकालिक को नहीं बना सकते हैं। यह कार्यक्षमता के लिए निर्भर करता है। लेकिन उदाहरण के लिए, वसंत में एक सेवा पद्धति जिसे कंट्रोलर विधि द्वारा पूर्ण भविष्य में लौटाया जाता है, उसे कॉल करने या सेवा पद्धति में शामिल नहीं होने के लिए अधिक समझ में आता है।
शैलेश वैशम्पायन

जवाबों:


110

एकमात्र अंतर यह है कि कैसे तरीके अपवाद फेंकते हैं। इंटरफ़ेस get()में घोषित किया Futureगया है

V get() throws InterruptedException, ExecutionException;

अपवाद दोनों कर रहे हैं जाँच अपवाद जो वे अपने कोड में नियंत्रित किया जा करने की जरूरत है का मतलब है। जैसा कि आप अपने कोड में देख सकते हैं कि आपके आईडीई में एक स्वचालित कोड जनरेटर ने पूछा है कि क्या आपकी ओर से ट्राइ-कैच ब्लॉक बनाया गया है।

try {
  CompletableFuture.allOf(fanoutRequestList).get() 
} catch (InterruptedException | ExecutionException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

join()विधि फेंक नहीं है जाँच अपवाद नहीं।

public T join()

इसके बजाय यह अनियंत्रित कंपोज़िशन अपवाद को फेंकता है । इसलिए आपको exceptionally()असंतुष्ट List<String> processफ़ंक्शन का उपयोग करते समय ट्राइ -कैच ब्लॉक की आवश्यकता नहीं है और इसके बजाय आप पूरी तरह से दोहन विधि का उपयोग कर सकते हैं

CompletableFuture<List<String>> cf = CompletableFuture
    .supplyAsync(this::process)
    .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException
    .thenAccept(this::processFurther);

आप दोनों get()और join()कार्यान्वयन यहाँ पा सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.