2017-02-28 5 views
8

मैं जावा 8 समरूपता सुविधाओं जैसे CompletableFuture पर नया हूं और मुझे आशा है कि आप निम्न उपयोग केस से शुरुआत करने में सहायता कर सकते हैं।जावा 8 - समानांतर में कॉल विधियों async और उनके परिणामों को गठबंधन करें

TimeConsumingServices नामक एक सेवा है जो समय लेने वाली परिचालन प्रदान करती है जो मैं समानांतर में चलाना चाहता हूं क्योंकि उनमें से सभी स्वतंत्र हैं।

interface TimeConsumingService { 

    default String hello(String name) { 
    System.out.println(System.currentTimeMillis() + " > hello " + name); 
    return "Hello " + name; 
    } 
    default String planet(String name) { 
    System.out.println(System.currentTimeMillis() + " > planet " + name); 
    return "Planet: " + name; 
    } 
    default String echo(String name) { 
    System.out.println(System.currentTimeMillis() + " > echo " + name); 
    return name; 
    } 

    default byte[] convert(String hello, String planet, String echo) { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(hello); 
    sb.append(planet); 
    sb.append(echo); 
    return sb.toString().getBytes(); 
    } 
} 

अब तक मैं निम्न उदाहरण लागू किया है और मैं समानांतर में सभी तीन सेवा तरीकों कॉल करने के लिए प्रबंधित किया है।

public class Runner implements TimeConsumingService { 

    public static void main(String[] args) { 
    new Runner().doStuffAsync(); 
    } 

    public void doStuffAsync() { 
    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> this.hello("Friend")); 
    CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> this.planet("Earth")); 
    CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> this.echo("Where is my echo?")); 

    CompletableFuture.allOf(future1, future2, future3).join(); 
    } 
} 

वहाँ एक रास्ता प्रत्येक सेवा कॉल के रिटर्न मूल्यों को इकट्ठा करने और विधि byte[]‘ convert(String, String, String) आह्वान करने के लिए है?

उत्तर

8

पर परिणाम संयोजित करने के लिए जाने के बाद उन्हें वापस आ गए सब आप इस

CompletableFuture<byte[]> byteFuture = CompletableFuture.allOf(cf1, cf2, cf3) 
        .thenApplyAsync(aVoid -> convert(cf1.join(), cf2.join(), cf3.join())); 
byte[] bytes = byteFuture.join(); 
की तरह कुछ कर सकते हैं

यह आपके सभी वायदा चलाएगा, उन सभी को पूरा करने की प्रतीक्षा करें, जैसे ही वे समाप्त हो जाएंगे, आपकेपर कॉल करेंगेविधि जिसका आप उल्लेख करते हैं।

2

बाद में शामिल होने आप बस की तरह future1 से get() मूल्यों कर सकते हैं:

String s1 = future1.get() 

और इतने

+0

लेकिन अगर मैं 'future1.get फोन(); future2.get(); future3.get(); 'वे समानांतर में नहीं बुलाए जाते हैं, है ना? – saw303

+2

जब आप future1.get() को कॉल करते हैं तो आप पहले से ही गणना किए गए परिणाम प्राप्त कर सकते हैं। –

+1

हां परिणाम प्राप्त करना समानांतर में नहीं कहा जाता है लेकिन सभी विधियों को अतुल्यकालिक रूप से गणना की जाएगी। आप इसे 'TimeUnit.seconds (2) जोड़ने के साथ देख सकते हैं। सोएं() '; विधि में शामिल होने के बाद। आप देखेंगे कि 'System.out.println' को उस नींद से पहले बुलाया गया था। – user2377971

0

आप उन्हें thenCombine() विधि का उपयोग करता है, तो वहाँ पूरा करने के लिए है केवल 3 वायदा गठजोड़ कर सकते हैं:

final CompletableFuture<byte[]> byteFuture = future1.thenCombine(future2, (t, u) -> { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(t); 
    sb.append(u); 
    return sb.toString(); 
}).thenCombine(future3, (t, u) -> { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(t); 
    sb.append(u); 
    return sb.toString(); 
}).thenApply(s -> s.getBytes()); 

try { 
    final byte[] get = byteFuture.get(); 
} catch (InterruptedException | ExecutionException ex) { 
} 
संबंधित मुद्दे