Java Language
CompletableFuture
खोज…
परिचय
कंप्लीटटेबल सीवन जावा एसई 8 में जोड़ा गया एक वर्ग है जो जावा एसई से भविष्य के इंटरफ़ेस को लागू करता है। भविष्य के इंटरफ़ेस का समर्थन करने के अलावा यह कई तरीके जोड़ता है जो भविष्य पूरा होने पर अतुल्यकालिक कॉलबैक की अनुमति देता है।
अवरुद्ध विधि को एसिंकोनस में बदलें
निम्नलिखित विधि एक वेब पेज को पुनः प्राप्त करने और पाठ की लंबाई की गणना करने के लिए आपके कनेक्शन के आधार पर एक या दो का समय लेगी। जो भी थ्रेड कहता है, वह उस अवधि के लिए ब्लॉक हो जाएगा। इसके अलावा यह एक अपवाद को पुनर्जीवित करता है जो बाद में उपयोगी है।
public static long blockingGetWebPageLength(String urlString) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(new URL(urlString).openConnection().getInputStream()))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString().length();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
यह इसे एक ऐसी विधि में परिवर्तित करता है जो अवरुद्ध विधि कॉल को दूसरे धागे पर ले जाकर तुरंत वापस आ जाएगी। डिफ़ॉल्ट रूप से supplyAsync विधि आपूर्तिकर्ता को सामान्य पूल पर चलाएगी। एक अवरुद्ध विधि के लिए यह शायद एक अच्छा विकल्प नहीं है क्योंकि कोई उस पूल में थ्रेड्स को समाप्त कर सकता है यही कारण है कि मैंने वैकल्पिक सेवा पैरामीटर जोड़ा है।
static private ExecutorService service = Executors.newCachedThreadPool();
static public CompletableFuture<Long> asyncGetWebPageLength(String url) {
return CompletableFuture.supplyAsync(() -> blockingGetWebPageLength(url), service);
}
एक अतुल्यकालिक फैशन में फ़ंक्शन का उपयोग करने के लिए, विधियों में से एक का उपयोग करना चाहिए जो एक लैमडा को स्वीकार करता है जिसे आपूर्तिकर्ता के परिणाम के साथ बुलाया जाता है जब यह तत्पश्चात पूरा हो जाता है। इसके अलावा किसी भी अपवाद को लॉग करने के लिए असाधारण या हैंडल विधि का उपयोग करना महत्वपूर्ण है जो हो सकता है।
public static void main(String[] args) {
asyncGetWebPageLength("https://stackoverflow.com/")
.thenAccept(l -> {
System.out.println("Stack Overflow returned " + l);
})
.exceptionally((Throwable throwable) -> {
Logger.getLogger("myclass").log(Level.SEVERE, "", throwable);
return null;
});
}
कंप्लीटटेबल सिवनी का सरल उदाहरण
नीचे दिए गए उदाहरण में, calculateShippingPrice
विधि शिपिंग लागत की गणना करती है, जिसमें कुछ प्रसंस्करण समय लगता है। एक वास्तविक दुनिया उदाहरण में, यह एक अन्य सर्वर से संपर्क करेगा जो उत्पाद के वजन और शिपिंग विधि के आधार पर कीमत लौटाता है।
इसे CompletableFuture
माध्यम से एक एस्किंट तरीके से मॉडलिंग करके, हम विधि में अलग-अलग काम जारी रख सकते हैं (यानी पैकेजिंग लागतों की गणना)।
public static void main(String[] args) {
int price = 15; // Let's keep it simple and work with whole number prices here
int weightInGrams = 900;
calculateShippingPrice(weightInGrams) // Here, we get the future
.thenAccept(shippingPrice -> { // And then immediately work on it!
// This fluent style is very useful for keeping it concise
System.out.println("Your total price is: " + (price + shippingPrice));
});
System.out.println("Please stand by. We are calculating your total price.");
}
public static CompletableFuture<Integer> calculateShippingPrice(int weightInGrams) {
return CompletableFuture.supplyAsync(() -> {
// supplyAsync is a factory method that turns a given
// Supplier<U> into a CompletableFuture<U>
// Let's just say each 200 grams is a new dollar on your shipping costs
int shippingCosts = weightInGrams / 200;
try {
Thread.sleep(2000L); // Now let's simulate some waiting time...
} catch(InterruptedException e) { /* We can safely ignore that */ }
return shippingCosts; // And send the costs back!
});
}