🔁 Callable vs Runnable
| Feature | Runnable | Callable<V> |
|---|---|---|
| Returns result? | ❌ No | ✅ Yes (generic type V) |
| Can throw exception? | ❌ No (must handle inside) | ✅ Yes (throws Exception) |
| Method to override | run() | call() |
✅ Example:
// Runnable
Runnable r = () -> System.out.println("No return");
// Callable
Callable<String> c = () -> {
return "Hello from callable!";
};
🧠 What is Future<V>?
A Future is like a promise or ticket to get the result of an asynchronous computation in the future.
You get a Future when you submit a Callable (or even a Runnable) to an ExecutorService.
✅ How They Work Together
ExecutorService executor = Executors.newSingleThreadExecutor();
// 1. Define a Callable
Callable<String> task = () -> {
Thread.sleep(1000); // simulate work
return "Task result";
};
// 2. Submit it to the executor
Future<String> future = executor.submit(task);
// 3. Get result (blocks until done)
String result = future.get(); // May throw InterruptedException or ExecutionException
System.out.println("Result: " + result);
executor.shutdown();
💡 Methods on Future
| Method | Purpose |
|---|---|
get() | Blocks and gets the result |
get(timeout, unit) | Waits with timeout |
isDone() | Checks if task is finished |
cancel(true/false) | Attempts to cancel the task |
isCancelled() | Checks if it was cancelled |
✅ Real Use Case
Imagine calling an API, processing a file, or computing something heavy in the background — Callable lets you do that in parallel and Future gives you the result later.