2014-12-31 10 views
19

कुछ की पुष्टि करने की आवश्यकता है। निम्नलिखित कोड:CompletableFuture, supplyAsync() और फिर लागू करें()

CompletableFuture 
    .supplyAsync(() -> { 
     A a = doSomethingAndReturnA(); 
     convertToB(a); 
}); 

अधिकार:

CompletableFuture 
    .supplyAsync(() -> {return doSomethingAndReturnA();}) 
    .thenApply(a -> convertToB(a)); 

के रूप में ही हो सकता है? क्या कोई कारण है कि हम thenApply का उपयोग क्यों करेंगे: 1) रूपांतरण के लिए बड़ा कोड या 2) अन्य स्थानों पर लैम्ब्डा ब्लॉक का पुन: उपयोग करने की आवश्यकता है?

उत्तर

38

यह है एक ही बात नहीं। दूसरे उदाहरण में जहां thenApply का उपयोग नहीं किया जाता है, यह निश्चित है कि convertToB पर कॉल विधि doSomethingAndReturnA विधि के समान थ्रेड में निष्पादित किया गया है।

लेकिन, पहले उदाहरण में जब thenApply विधि प्रयोग किया जाता है अन्य बातों के हो सकता है।

सबसे पहले, जो doSomethingAndReturnA निष्पादित करता है पूरा हो गया है, thenApply का आवेषण कॉलर थ्रेड में होगा। यदि CompletableFuturesFunctionthenApply के लिए पारित doSomethingAndReturnA रूप में एक ही धागे में सक्रिय किया जाएगा नहीं पूरा हो चुका है।

उलझन में? खैर this article might be helpful (लिंक के लिए @SotiriosDelimanolis धन्यवाद)।

मैं एक छोटी उदाहरण से बताया है कि कैसे काम करता है thenApply प्रदान की है।

public class CompletableTest { 
    public static void main(String... args) throws ExecutionException, InterruptedException { 
     final CompletableFuture<Integer> future = CompletableFuture 
       .supplyAsync(() -> doSomethingAndReturnA()) 
       .thenApply(a -> convertToB(a)); 

     future.get(); 
    } 

    private static int convertToB(final String a) { 
     System.out.println("convertToB: " + Thread.currentThread().getName()); 
     return Integer.parseInt(a); 
    } 

    private static String doSomethingAndReturnA() { 
     System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName()); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     return "1"; 
    } 
} 

और उत्पादन होता है:

doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1 
convertToB: ForkJoinPool.commonPool-worker-1 

तो, जब पहला ऑपरेशन (अर्थात CompletableFuture अभी तक पूर्ण नहीं है) धीमी है दोनों कॉल को एक ही धागे में होते हैं। लेकिन अगर हम उत्पादन doSomethingAndReturnA से Thread.sleep -call दूर करने के लिए थे, वे इस तरह (हो सकता है):

doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1 
convertToB: main 

ध्यान दें कि convertToB कॉल main सूत्र में है।

+1

यह उत्तर और यह पोस्ट (http://www.deadcoderising.com/java8-writing-asynchronous-code-with -completablefuture /) CompletableFuture – Jesus

+0

को समझने में मेरी सहायता करें यह अभी भी यह नहीं समझाता है कि कोई 'तब लागू' क्यों उपयोग करेगा? – Yamcha

+0

पहले मामले में, '' 'ForkJoinPool.commonPool-worker-1'' 'बस वहां लटका है और' कुछ' और कुछ और रिटर्न ''' '' '' '' '' 'कुछ और इंतजार कर रहा है? – Siddhartha

2

thenApply() कॉलबैक फ़ंक्शन, जो जब supplyAsync() मान निष्पादित किया जाएगा है।

कोड स्निपेट 2 में, थ्रेड जो कुछ किया जाता है कुछ और एंड्रेटए() निष्पादित करने और डेटा वापस करने के लिए फ़ंक्शन के लिए प्रतीक्षा करता है। लेकिन कुछ अपवाद मामलों में (जैसे webservice कॉल करना और प्रतिक्रिया की प्रतीक्षा करना), थ्रेड को प्रतिक्रिया प्राप्त करने के लिए लंबी अवधि का इंतजार करना पड़ता है, जो बदले में बहुत से सिस्टम संसाधनों का उपभोग करता है (केवल प्रतिक्रिया के लिए प्रतीक्षा करने के लिए)।

इससे बचने के लिए, पूर्ण भविष्य में कॉलबैक सुविधा के साथ आता है, जहां एक बार doSomethingAndReturnA() का आह्वान किया जाता है, एक अलग थ्रेड निष्पादित करने का ख्याल रखता है कुछ औरAndeturnA() और मुख्य कॉलर थ्रेड अन्य ऑपरेशन करना जारी रखेगा वापस लौटने की प्रतिक्रिया। एक बार doSomethingAndReturnA की प्रतिक्रिया उपलब्ध हो जाने पर, कॉल बैक विधि लागू की जाएगी (यानी, फिर लागू करें))

संबंधित मुद्दे