📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
✅ Some premium posts are free to read — no account needed. Follow me on Medium to stay updated and support my writing.
🎓 Top 10 Udemy Courses (Huge Discount): Explore My Udemy Courses — Learn through real-time, project-based development.
▶️ Subscribe to My YouTube Channel (172K+ subscribers): Java Guides on YouTube
The Executors
class in Java provides factory methods to create Callable
objects. These methods are useful for wrapping tasks that implement the Runnable
interface or for tasks that return a result. This guide will cover the usage of Executors.callable()
methods, explain how they work, and provide concise examples to demonstrate their functionality in real-world use cases.
Introduction
The Executors.callable()
methods are used to create Callable
objects from various types of tasks, including Runnable
tasks and tasks that return a specific result. These methods provide flexibility in converting tasks to Callable
instances, which can be used with an ExecutorService
for concurrent execution.
Overloaded Methods
1. callable(Runnable task)
This method wraps a Runnable
task into a Callable
that returns null
upon completion.
Syntax
public static Callable<Object> callable(Runnable task)
2. callable(Runnable task, T result)
This method wraps a Runnable
task into a Callable
that returns a specified result upon completion.
Syntax
public static <T> Callable<T> callable(Runnable task, T result)
3. callable(PrivilegedAction<T> action)
This method wraps a PrivilegedAction
task into a Callable
that returns the result of the action.
Syntax
public static <T> Callable<T> callable(PrivilegedAction<T> action)
4. callable(PrivilegedExceptionAction<T> action)
This method wraps a PrivilegedExceptionAction
task into a Callable
that returns the result of the action and can throw checked exceptions.
Syntax
public static <T> Callable<T> callable(PrivilegedExceptionAction<T> action)
Examples
Example 1: Wrapping a Runnable
Task
In this example, we wrap a Runnable
task into a Callable
that returns null
upon completion.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable task = () -> System.out.println("Executing runnable task");
Callable<Object> callableTask = Executors.callable(task);
Future<Object> future = executor.submit(callableTask);
try {
future.get();
System.out.println("Task completed successfully");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Output:
Executing runnable task
Task completed successfully
Example 2: Wrapping a Runnable
Task with a Result
In this example, we wrap a Runnable
task into a Callable
that returns a specified result upon completion.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableWithResultExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable task = () -> System.out.println("Executing runnable task with result");
Callable<String> callableTask = Executors.callable(task, "Task result");
Future<String> future = executor.submit(callableTask);
try {
String result = future.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Output:
Executing runnable task with result
Result: Task result
Example 3: Wrapping a PrivilegedAction
Task
In this example, we wrap a PrivilegedAction
task into a Callable
that returns the result of the action.
import java.security.PrivilegedAction;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PrivilegedActionExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
PrivilegedAction<String> action = () -> "Privileged action result";
Callable<String> callableTask = Executors.callable(action);
Future<String> future = executor.submit(callableTask);
try {
String result = future.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Output:
Result: Privileged action result
Example 4: Wrapping a PrivilegedExceptionAction
Task
In this example, we wrap a PrivilegedExceptionAction
task into a Callable
that returns the result of the action and can throw checked exceptions.
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PrivilegedExceptionActionExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
PrivilegedExceptionAction<String> action = () -> "Privileged exception action result";
Callable<String> callableTask = Executors.callable(action);
Future<String> future = executor.submit(callableTask);
try {
String result = future.get();
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Output:
Result: Privileged exception action result
Conclusion
The Executors.callable()
methods in Java are useful for wrapping different types of tasks into Callable
objects. These methods provide flexibility in converting Runnable
, PrivilegedAction
, and PrivilegedExceptionAction
tasks into Callable
instances, making them suitable for concurrent execution with an ExecutorService
.
Comments
Post a Comment
Leave Comment