Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Java

Java 9 में CompletableFuture और Future के बीच अंतर

Java 5 में पेश किया गया Future<T> इंटरफेस एसिंक्रोनस गणना के परिणाम का प्रतिनिधित्व करता है। Java 8 ने CompletableFuture<T> जोड़ा जो Future<T> को लागू करता है और शक्तिशाली संयोजन क्षमताएं प्रदान करता है।

मुख्य अंतर अवलोकन

विशेषताFuture<T>CompletableFuture<T>
ब्लॉकिंग get()हां - get() ब्लॉक करता हैवैकल्पिक - गैर-ब्लॉकिंग चेनिंग
कॉलबैक/चेनिंगनहींहां - thenApply, thenAccept, thenCompose
कई Futures संयोजित करेंमैन्युअल, जटिलallOf, anyOf, thenCombine
असाधारण संचालनकेवल get() परexceptionally, handle, whenComplete
मैन्युअल पूर्णतानहीं (केवल ExecutorService के माध्यम से)हां - complete(), completeExceptionally()
इंटरफेसFutureFuture + CompletionStage

Future की सीमाएं

// Future के साथ समस्या: ब्लॉकिंग get()
ExecutorService executor = Executors.newFixedThreadPool(2);

Future future1 = executor.submit(() -> {
    Thread.sleep(1000);
    return 10;
});

Future future2 = executor.submit(() -> {
    Thread.sleep(1000);
    return 20;
});

// परिणामों को संयोजित करने के लिए - दोनों get() पर ब्लॉक करना होगा!
int result = future1.get() + future2.get(); // 2 सेकंड ब्लॉक करता है
// कोई तरीका नहीं कहने का: "जब दोनों पूरे हों, तो उन्हें जोड़ें"

CompletableFuture समाधान

// गैर-ब्लॉकिंग चेनिंग
CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> {
    Thread.sleep(1000);
    return 10;
});

CompletableFuture cf2 = CompletableFuture.supplyAsync(() -> {
    Thread.sleep(1000);
    return 20;
});

// समानांतर निष्पादन, फिर संयोजन - कोई ब्लॉकिंग नहीं!
CompletableFuture combined = cf1.thenCombine(cf2, (a, b) -> a + b);

// बाद में परिणाम प्राप्त करें (या जारी रखें चेनिंग)
combined.thenAccept(sum -> System.out.println("योग: " + sum)); // 30 प्रिंट करता है

// मुख्य थ्रेड अन्य काम कर सकता है
System.out.println("मुख्य थ्रेड मुक्त है!");

पूर्ण उदाहरण: मूल लेख से

import java.util.function.Supplier;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureTest {
    public static void main(String args[]) throws ExecutionException, InterruptedException {
        Calculator calc = new Calculator(4, 7);
        
        // एसिंक्रोनस सप्लाई
        CompletableFuture future = CompletableFuture.supplyAsync(calc);
        
        // गैर-ब्लॉकिंग कॉलबैक
        future.thenAccept(result -> {
            System.out.println("परिणाम: " + result); // 3 सेकंड बाद प्रिंट होता है
        });
        
        System.out.println("CompletableFutureTest End...."); // तुरंत प्रिंट होता है
        
        // मुख्य थ्रेड को जीवित रखें ताकि डेमॉन थ्रेड पूरा हो सके
        Thread.sleep(10000);
    }
}

class Calculator implements Supplier {
    private int x, y;
    public Calculator(int x, int y) { this.x = x; this.y = y; }
    
    @Override
    public Integer get() {
        try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
        return x + y; // 11 लौटाता है
    }
}
आउटपुट:
CompletableFutureTest End....
11

CompletableFuture मुख्य मेथड्स

परिवर्तन (Transformation)

// thenApply: परिणाम बदलें, नया CompletableFuture लौटाएं
CompletableFuture strFuture = future.thenApply(i -> "परिणाम: " + i);

// thenCompose: दूसरा एसिंक्रोनस ऑपरेशन चेन करें (फ्लैटमैप)
CompletableFuture chained = future.thenCompose(i -> fetchDetailsAsync(i));

उपभोग (Consumption)

// thenAccept: परिणाम का उपभोग करें, कुछ न लौटाएं (void)
future.thenAccept(System.out::println);

// thenRun: परिणाम की अनदेखी करें, बस एक्शन चलाएं
future.thenRun(() -> System.out.println("किया!"));

संयोजन (Combination)

// thenCombine: दो स्वतंत्र futures संयोजित करें
cf1.thenCombine(cf2, (a, b) -> a + b)

// allOf: सभी पूरे होने की प्रतीक्षा करें (कोई परिणाम नहीं)
CompletableFuture all = CompletableFuture.allOf(cf1, cf2, cf3);
all.thenRun(() -> System.out.println("सभी पूरे!"));

// anyOf: किसी एक के पूरा होने की प्रतीक्षा करें
CompletableFuture any = CompletableFuture.anyOf(cf1, cf2, cf3);


त्रुटि संचालन

// exceptionally: त्रुटि से उबरें
future.exceptionally(ex -> {
    System.err.println("त्रुटि: " + ex.getMessage());
    return -1; // डिफ़ॉल्ट मान
});

// handle: सफलता और विफलता दोनों संभालें
future.handle((result, ex) -> {
    if (ex != null) return "विफल: " + ex.getMessage();
    return "सफल: " + result;
});

// whenComplete: पूरा होने पर साइड इफेक्ट
future.whenComplete((result, ex) -> {
    if (ex != null) ex.printStackTrace();
    else System.out.println("पूर्ण: " + result);
});

मैन्युअल पूर्णता

// प्रोग्रामेटिक रूप से CompletableFuture बनाएं और पूरा करें
CompletableFuture manual = new CompletableFuture<>();

// बाद में किसी अन्य थ्रेड में...
manual.complete("हैलो वर्ल्ड"); // या
manual.completeExceptionally(new RuntimeException("कुछ गलत हुआ"));

// उपभोक्ता इसे सामान्य Future की तरह उपयोग करते हैं
manual.thenAccept(System.out::println);

सर्वोत्तम अभ्यास

  • डिफ़ॉल्ट एक्जीक्यूटर से बचें: supplyAsync(() -> ..., customExecutor) का उपयोग करें
  • अपवादों को संभालें: हमेशा .exceptionally() या .handle() जोड़ें
  • ब्लॉकिंग से बचें: get()/join() के बजाय चेनिंग का उपयोग करें
  • रद्दीकरण: cancel(true) इंटरप्ट करता है; CompletionException फेंक सकता है
  • CompletionStage: लचीलेपन के लिए CompletableFuture के बजाय इस इंटरफेस के लिए प्रोग्राम करें

कब क्या उपयोग करें

  • Future: सरल एसिंक्रोनस कार्य, लीगेसी कोड, जब ब्लॉकिंग स्वीकार्य हो
  • CompletableFuture: जटिल वर्कफ्लो, समानांतर संयोजन, रिएक्टिव पैटर्न, आधुनिक Java एप्लिकेशन
  1. - जावा में org.simple.json और org.json लाइब्रेरीज के बीच अंतर

    org.json.simple लाइब्रेरी हमें जावा में JSON डेटा को पढ़ने और लिखने की अनुमति देती है। दूसरे शब्दों में, हम JSON ऑब्जेक्ट को एनकोड और डीकोड कर सकते हैं। org.json.simple पैकेज में JSONValue, JSONObject, JSONArray, JsonString और JsonNumber जैसी महत्वपूर्ण क्लासेस होती हैं। JSON प्रोग्राम चलाने के लिए

  1. - जावा में Collection और Collections में अंतर?

    Collection एक इंटरफेस है जबकि Collections जावा में एक यूटिलिटी क्लास है। Set, List, और Queue Collection इंटरफेस के कुछ सबइंटरफेस हैं, एक Map इंटरफेस भी Collections फ्रेमवर्क का हिस्सा है, लेकिन यह Collection इंटरफेस को इनहेरिट नहीं करता। Collection इंटरफेस के महत्वपूर्ण मेथड्स हैं add(), remove(),

  1. - जावा में wait() और sleep() मेथड में अंतर?

    sleep() मेथड Thread क्लास का एक स्टैटिक मेथड है और यह वर्तमान रनिंग थ्रेड को नॉन-रनेबल स्थिति में भेज सकता है जबकि wait() मेथड एक इंस्टेंस मेथड है, हम इसे थ्रेड ऑब्जेक्ट का उपयोग करके बुलाते हैं और यह केवल उस ऑब्जेक्ट के लिए प्रभावी होता है। sleep() मेथड समय समाप्त होने या interrupt() मेथड बुलाए जा