2016-06-20 6 views
5

तो मेरे पास एक तरीका है जो CompletableFuture देता है। लौटने से पहले, यह विधि thenAccept के साथ एक ब्लॉक जोड़ती है जिसे CompletableFuture पूर्ण होने के बाद निष्पादित किया जाता है।ऑर्डर क्या है जिसमें एक पूर्णत: फिक्स्डटेबल के ब्लॉक को स्वीकार किया जाता है

इस विधि के कॉलर भी thenAccept के साथ एक और ब्लॉक जोड़ता है। जाहिर है यह कई जंजीर कॉल के साथ जा सकता है।

CompletionStagethenAccept द्वारा निष्पादित किए गए आदेशों को किस क्रम में निष्पादित किया गया है? क्या यह आदेश होने की गारंटी है जिसमें उन्हें जोड़ा जाता है? यदि नहीं, तो कोई गारंटी कैसे दे सकता है कि उन्हें उस क्रम में निष्पादित किया गया है जिसमें उन्हें जोड़ा गया है?

पुनश्च: मैं इस CompletableFuture साथ मेरे अपने अनुभव के आधार पर पूछ रहा हूँ और इस article

+2

"तब स्वीकार करें" का अर्थ है कि पहले "यह" CompletableFuture पूरा हो गया है, और केवल तब पैरामीटर फ़ंक्शन निष्पादित किया गया है। –

उत्तर

6

आप उन्हें चेनिंग तक पूरा करने के चरणों की निर्भरता मॉडल कर रहे हैं। आप दो कार्यों A और B एक अन्य कार्रवाई C को श्रृंखला हैं, तो आप को परिभाषित रिश्तों A → C और B → C, लेकिन A और B और इसलिए बीच कोई रिश्ता नहीं है, वहाँ दूसरे शब्दों में कोई आदेश देने के संबंध, उन दोनों के बीच कोई रिश्ता नहीं सहित, है, आप कर सकते हैं 'टी भी, कि एक के बाद एक चलेंगे मान यानी

CompletableFuture<String> base=CompletableFuture.supplyAsync(() -> { 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
    return "source"; 
}); 
base.thenAccept(s -> { 
    System.out.println("entered first consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving first consumer"); 
}); 
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
base.thenAccept(s -> { 
    System.out.println("entered second consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving second consumer"); 
}); 

entered first consumer in Thread[ForkJoinPool.commonPool-worker-1,5,main] 
entered second consumer in Thread[main,5,main] 
leaving second consumer 
leaving first consumer 

हालांकि तरह बहुत संभावना प्रिंट कुछ जाहिर है, इसके बारे में कोई गारंटी है होगा।


दो उपभोक्ताओं के बीच अपनी निर्भरता को लागू करने के लिए, आपको उन्हें उचित रूप से श्रृंखलाबद्ध करना होगा, उदा।

CompletableFuture<String> base=CompletableFuture.supplyAsync(() -> { 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
    return "source"; 
}); 
CompletableFuture<Void> next = base.thenAccept(s -> { 
    System.out.println("entered first consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving first consumer"); 
}); 
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2)); 
base.thenAcceptBoth(next, (s,ignored) -> { 
    System.out.println("entered second consumer in "+Thread.currentThread()); 
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); 
    System.out.println("leaving second consumer"); 
}).join(); 

इधर, दूसरा उपभोक्ता base से परिणाम प्राप्त करने के लिए base और next, को श्रृंखलित है, लेकिन next के पूरा होने पर निर्भर करती है (यदि वहाँ पास-शायद करने के लिए कोई परिणाम है आप सामान्य रूप से की आवश्यकता नहीं होगी जो यदि आपके पास ऐसा परिदृश्य है, तो आप अपने डिज़ाइन पर पुनर्विचार करना चाहते हैं)।

वैकल्पिक रूप से, आप एक Function जो मूल्य से होकर गुजरता है करने के लिए पहली Consumer परिवर्तित कर सकते हैं, तो आप thenApply के माध्यम से यह श्रृंखला सकते हैं, यह करने के लिए एक और thenAccept चरण चेनिंग अनुमति देने के लिए।

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

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