← Back to Advanced Java Course | Chapter 2: Multithreading | Lesson 7 of 8

Java Callable और Future

एक Callable एक ऐसा job है जो एक result वापस देता है, और एक Future एक ऐसा ticket है जिसका उपयोग आप बाद में वह result लेने के लिए करते हैं, जैसे किसी bakery की claim ticket। आप जवाब तैयार होने पर उसे ले सकते हैं।
Syntax
java
Callable<ResultType> task = () -> {
    return result;
};
Future<ResultType> future = executor.submit(task);
ResultType result = future.get();

What is Callable?

Callable interface एक asynchronous task को represent करता है, Runnable जैसा ही, लेकिन दो मुख्य अंतरों के साथ: एक Callable अपने call() method से एक computed value return कर सकता है, और यह execution के दौरान checked exceptions फेंक सकता है, जो Runnable का run() नहीं कर सकता।

उदाहरण: What is Callable?

java
// Import java.util.concurrent.* so it can be used by its short name
import java.util.concurrent.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws Exception {
		Callable<Integer> task = () -> {
			if (false) throw new Exception("checked exception allowed");
			// Send 5 * 5 back to the caller
			return 5 * 5;
		};
		// Print a line to the console
		System.out.println(task.call());
	}
}

What is Future?

एक Future किसी executor को submit किए गए asynchronous task के अंतिम, pending result को represent करता है। आप पूर्णता की स्थिति जांचने के लिए इसे isDone() से poll कर सकते हैं, या जवाब तैयार होने तक block करने और उसे निकालने के लिए get() call कर सकते हैं।

उदाहरण: What is Future?

java
// Import java.util.concurrent.* so it can be used by its short name
import java.util.concurrent.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws Exception {
		// Create a thread pool to run tasks
		ExecutorService executor = Executors.newSingleThreadExecutor();
		Future<Integer> future = executor.submit(() -> 100);
		// Print a line to the console
		System.out.println(future.isDone());
		// Print a line to the console
		System.out.println(future.get());
		executor.shutdown();
	}
}

Handling Exceptions with Future

अगर कोई Callable task execution के दौरान exception फेंकता है, तो वह exception तुरंत propagate नहीं होता — इसे framework capture करके wrap कर देता है। जब आप बाद में Future.get() call करते हैं, तो यह उस failure को ExecutionException में wrap करके फिर से throw करता है, original exception getCause() के ज़रिए उपलब्ध होता है।

उदाहरण: Handling Exceptions with Future

java
// Import java.util.concurrent.* so it can be used by its short name
import java.util.concurrent.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a thread pool to run tasks
		ExecutorService executor = Executors.newSingleThreadExecutor();
		Future<Integer> future = executor.submit(() -> { throw new RuntimeException("task failed"); });
		// Try code that might throw an exception
		try {
			future.get();
		// Handle ExecutionException if it was thrown
		} catch (ExecutionException e) {
			// Print a line to the console
			System.out.println("Caught: " + e.getCause().getMessage());
		}
		executor.shutdown();
	}
}

Multiple Callables with invokeAll()

आप किसी ExecutorService के invokeAll() method का उपयोग करके कई Callable tasks को parallel में चला सकते हैं, जो हर task को एक साथ submit करता है और जब तक वे सभी पूरे न हो जाएं तब तक block करता है। यह उसी order में Future objects की एक List return करता है जिस order में tasks submit किए गए थे, आपको हर result अलग-अलग निकालने देते हुए।

उदाहरण: Multiple Callables with invokeAll()

java
// Import java.util.* so it can be used by its short name
import java.util.*;
// Import java.util.concurrent.* so it can be used by its short name
import java.util.concurrent.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws Exception {
		// Create a thread pool to run tasks
		ExecutorService executor = Executors.newFixedThreadPool(2);
		List<Callable<Integer>> tasks = List.of(() -> 1 + 1, () -> 2 + 2, () -> 3 + 3);
		List<Future<Integer>> results = executor.invokeAll(tasks);
		for (Future<Integer> f : results) System.out.println(f.get());
		executor.shutdown();
	}
}

Best Practices with Future

अपने application को किसी hung task पर अनिश्चित काल तक block होने से रोकने के लिए, बिना-argument वाले overload को call करने के बजाय हमेशा Future.get(timeout, unit) को एक timeout पास करें। यह भी अच्छी practice है कि हर executor service को एक finally block के अंदर shut down करें ताकि यह किसी task के throw करने पर भी release हो जाए।

उदाहरण: Best Practices with Future

java
// Import java.util.concurrent.* so it can be used by its short name
import java.util.concurrent.*;
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Create a thread pool to run tasks
		ExecutorService executor = Executors.newSingleThreadExecutor();
		// Try code that might throw an exception
		try {
			Future<Integer> future = executor.submit(() -> 42);
			// Print a line to the console
			System.out.println(future.get(2, TimeUnit.SECONDS));
		// Handle Exception if it was thrown
		} catch (Exception e) {
			// Print a line to the console
			System.out.println("Timed out or failed");
		} finally {
			executor.shutdown();
		}
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. future.get() को बिना timeout के call करना, जिससे अगर task हैंग हो जाए तो program हमेशा के लिए block हो सकता है; get(timeout, unit) का उपयोग करें।
  2. सिर्फ task के exception type को catch करना, जबकि get() इसे एक ExecutionException में wrap करता है और आपको e.getCause() पढ़ना चाहिए।
  3. यह भूल जाना कि get() जवाब तैयार होने तक block करता है, और इसे सभी tasks submit करने से पहले main thread पर call करना, जो parallelism हटा देता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.