CompletableFuture in Java: एक पूर्ण गाइड
Java में CompletableFuture एक शक्तिशाली क्लास है जो एसिंक्रोनस प्रोग्रामिंग (Asynchronous Programming) को आसान बनाता है। यह Java 8 में पेश किया गया था और Future
इंटरफेस का एक एडवांस्ड वर्जन है। CompletableFuture
का उपयोग करके हम नॉन-ब्लॉकिंग कोड लिख सकते हैं, जिससे एप्लिकेशन की परफॉरमेंस बेहतर होती है।
इस ब्लॉग में हम CompletableFuture के बारे में विस्तार से जानेंगे, इसके विभिन्न मेथड्स को समझेंगे और उदाहरणों के साथ देखेंगे कि इसे कैसे और कब उपयोग करना चाहिए।
1. CompletableFuture क्या है?
CompletableFuture
एक क्लास है जो Future और CompletionStage इंटरफेस को इम्प्लीमेंट करता है। यह हमें:
एसिंक्रोनस टास्क्स (Asynchronous Tasks) को रन करने देता है।
कॉलबैक (Callbacks) जोड़ने की सुविधा देता है।
मल्टीपल फ्यूचर्स को कॉम्बाइन (Combine Multiple Futures) करने की अनुमति देता है।
एक्सेप्शन हैंडलिंग (Exception Handling) प्रदान करता है।
2. CompletableFuture बनाने के तरीके
(1) runAsync()
- कोई रिजल्ट नहीं देता (Runnable)
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Task running asynchronously in: " + Thread.currentThread().getName()); }); future.get(); // ब्लॉक करके रिजल्ट का इंतजार करता है
आउटपुट:
Task running asynchronously in: ForkJoinPool.commonPool-worker-1
(2) supplyAsync()
- रिजल्ट देता है (Supplier)
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Hello from CompletableFuture!"; }); System.out.println(future.get());
आउटपुट:
Hello from CompletableFuture!
3. CompletableFuture के मुख्य मेथड्स
(1) thenApply()
- रिजल्ट को ट्रांसफॉर्म करता है
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Java") .thenApply(name -> "Hello, " + name); System.out.println(future.get()); // Hello, Java
(2) thenAccept()
- रिजल्ट को कंज्यूम करता है (कोई रिटर्न नहीं)
CompletableFuture.supplyAsync(() -> "Java") .thenAccept(result -> System.out.println("Received: " + result)); // Received: Java
(3) thenRun()
- रिजल्ट के बाद एक एक्शन परफॉर्म करता है
CompletableFuture.supplyAsync(() -> "Java") .thenRun(() -> System.out.println("Task Completed!")); // Task Completed!
(4) thenCompose()
- मल्टीपल फ्यूचर्स को चेन करता है
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello") .thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " World")); System.out.println(future.get()); // Hello World
(5) thenCombine()
- दो फ्यूचर्स के रिजल्ट्स को कॉम्बाइन करता है
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World"); CompletableFuture<String> combined = future1.thenCombine(future2, (res1, res2) -> res1 + " " + res2); System.out.println(combined.get()); // Hello World
(6) allOf()
- सभी फ्यूचर्स के कंप्लीट होने का इंतजार करता है
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Task 1"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2"); CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "Task 3"); CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3); allFutures.get(); // सभी टास्क्स कंप्लीट होने तक इंतजार करता है
(7) anyOf()
- कोई भी एक फ्यूचर कंप्लीट होने पर आगे बढ़ता है
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "Result 1"; }); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result 2"); CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2); System.out.println(anyFuture.get()); // Result 2 (पहले कंप्लीट होगा)
(8) exceptionally()
- एरर हैंडलिंग के लिए
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { if (true) throw new RuntimeException("Error Occurred!"); return "Success"; }).exceptionally(ex -> "Handled: " + ex.getMessage()); System.out.println(future.get()); // Handled: java.lang.RuntimeException: Error Occurred!
(9) handle()
- सक्सेस और एरर दोनों को हैंडल करता है
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Success"; }).handle((result, ex) -> { if (ex != null) return "Error: " + ex.getMessage(); else return result; }); System.out.println(future.get()); // Success
4. CompletableFuture का उपयोग कब करें?
एसिंक्रोनस टास्क्स चलाने के लिए (जैसे API कॉल, डेटाबेस ऑपरेशन)।
पैरलल प्रोसेसिंग करने के लिए (मल्टीपल इंडिपेंडेंट टास्क्स)।
कॉलबैक-बेस्ड ऑपरेशन्स के लिए।
कॉम्प्लेक्स टास्क चेनिंग (एक टास्क का आउटपुट दूसरे का इनपुट हो)।
5. पूरा उदाहरण: मल्टीपल एसिंक्रोनस टास्क्स
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class CompletableFutureDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { // टास्क 1: यूजर का नाम लाएं CompletableFuture<String> getUserName = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Rahul"; }); // टास्क 2: यूजर का ईमेल लाएं CompletableFuture<String> getUserEmail = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } return "rahul@example.com"; }); // दोनों टास्क्स के रिजल्ट्स को कॉम्बाइन करें CompletableFuture<String> combinedFuture = getUserName.thenCombine(getUserEmail, (name, email) -> "Name: " + name + ", Email: " + email); System.out.println(combinedFuture.get()); // Output: Name: Rahul, Email: rahul@example.com } }
6. निष्कर्ष
CompletableFuture
Java में एसिंक्रोनस प्रोग्रामिंग को सरल और शक्तिशाली बनाता है। इसके द्वारा:
✔ नॉन-ब्लॉकिंग कोड लिखा जा सकता है।
✔ मल्टीपल टास्क्स को कॉम्बाइन किया जा सकता है।
✔ एक्सेप्शन्स को हैंडल किया जा सकता है।
✔ कॉलबैक्स जोड़कर कोड को और फ्लेक्सिबल बनाया जा सकता है।
इसका उपयोग मल्टीथ्रेडेड एप्लिकेशन्स, REST API कॉल्स, डेटाबेस ऑपरेशन्स आदि में किया जा सकता है।