Runnable, Callable, Future, Executor in Java & Android Multithreaded Programming
Last Updated :
10 Jan, 2023
Multithreading is a Java feature that allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such a program is called a thread. So, threads are lightweight processes within a process.
Runnable
Any class whose instances are intended to be executed by a thread should implement the Runnable interface. The class must define a run method with no arguments. This interface is intended to provide a standard protocol for objects that want to run code while they are active. Thread, for example, implements the Runnable interface. Being active simply means that a thread has begun and has not yet been terminated. Furthermore, Runnable allows a class to be active while not subclassing Thread. A class that implements Runnable can execute code without subclassing Thread by creating a Thread instance and passing itself as the target.
To create a new Thread with Runnable, follow these steps:
- Make a Runnable implementer and call the run() method.
- Create a Thread instance and pass the implementer to it. Thread has a function Object() { [native code] } that accepts Runnable instances.
- Call start() on the Thread instance; start calls the implementer's run() internally. Invoking start() generates a new Thread that executes the code specified in run ().
Java
public class Comment implements Activity {
private Date GeeksCreatedAt;
public Comment(Date GeeksCreatedAt)
{
this.GeeksCreatedAt = GeeksCreatedAt;
}
@Override public Date getCoursesAddedAt()
{
return GeeksCreatedAt;
}
@Override public String toString()
{
return "Comment{"
+ "GeeksCreatedAt=" + GeeksCreatedAt + '}';
}
}
public class GfG implements Activity {
private Date GeeksCreatedAt;
public GfG(Date GeeksCreatedAt)
{
this.GeeksCreatedAt = GeeksCreatedAt;
}
@Override public Date getCoursesAddedAt()
{
return GeeksCreatedAt;
}
@Override public String toString()
{
return "GfG{"
+ "GeeksCreatedAt=" + GeeksCreatedAt + '}';
}
}
Callable
A task that produces a result and has the ability to throw an exception. Implementers define a single method called call that takes no arguments. The Callable interface is similar to the Runnable interface in that both are intended for classes whose instances may be executed by another thread. A Runnable, on the other hand, does not return a value and cannot throw a checked exception. Executors contain utility methods for converting from other common forms to Callable classes. In order to implement a Runnable, the run() method must be implemented, which does not return anything, whereas, in order to implement a Callable, the call() method must be implemented, which returns a result on completion. It is important to note that a thread cannot be created with a Callable; only a Runnable can do so. Another distinction is that the call() method can throw an exception, whereas the run() method cannot.
Java
public class Like implements Activity {
private Date GeeksCreatedAt;
public Like(Date GeeksCreatedAt)
{
this.GeeksCreatedAt = GeeksCreatedAt;
}
@Override public Date getCreatedAt()
{
return GeeksCreatedAt;
}
@Override public String toString()
{
return "Like{"
+ "GeeksCreatedAt=" + GeeksCreatedAt + '}';
}
}
Java
public class Post implements Activity {
private Date GeeksCreatedAt;
public Post(Date GeeksCreatedAt)
{
this.GeeksCreatedAt = GeeksCreatedAt;
}
@Override public Date getCreatedAt()
{
return GeeksCreatedAt;
}
@Override public String toString()
{
return "Post{"
+ "GeeksCreatedAt=" + GeeksCreatedAt + '}';
}
}
Future
A Future is the outcome of an asynchronous computation. Methods are provided to determine whether the computation is complete, to wait for its completion, and to retrieve the computation's result. When the computation is finished, the result can only be retrieved using method get, blocking if necessary until it is ready. The cancel method is used to cancel a transaction. Additional methods are provided to determine whether or not the task was completed normally. Once a computation has been completed, it cannot be canceled. If you want to use a Future for cancellability but not provide a usable result, you can declare Future? types and return null as a result of the underlying task. Because it implements the Future interface, all interactions with the thread after it starts are handled by the FutureTask object. As a result, there is no need to save the Thread objects. The FutureTask object can be used to cancel the task, check if it is complete, or try to retrieve the result.
Java
public class RemoteService {
private static int cores
= Runtime.getRuntime().availableProcessors();
private static ExecutorService executor
= Executors.newFixedThreadPool(cores + 1);
public void stop() { executor.shutdown(); }
public void
getUserRecentGfgActs(ResultCallback callback)
{
executor.execute(() -> {
List<Like> gfgLikes = new ArrayList<>();
List<Post> gfgPOsts = new ArrayList<>();
List<Comment> comments = new ArrayList<>();
List<Friend> gfgCourses = new ArrayList<>();
Future<List<Like> > futureGfgLikes
= executor.submit(getGfgLikes(
"https://geeksforgeeks.org.com/gfgLikes"));
Future<List<Comment> > futureComments
= executor.submit(getComments(
"https://geeksforgeeks.org.com/comments"));
Future<List<Post> > futureGfgPOsts
= executor.submit(getGfgPOsts(
"https://geeksforgeeks.org.com/gfgPOsts"));
Future<List<Friend> > futureGfgCourses
= executor.submit(getGfgCourses(
"https://geeksforgeeks.org.com/gfgCourses"));
try {
gfgLikes = futureGfgLikes.get();
}
catch (InterruptedException
| ExecutionException e) {
e.printStackTrace();
}
try {
gfgPOsts = futureGfgPOsts.get();
}
catch (InterruptedException
| ExecutionException e) {
e.printStackTrace();
}
try {
comments = futureComments.get();
}
catch (InterruptedException
| ExecutionException e) {
e.printStackTrace();
}
try {
gfgCourses = futureGfgCourses.get();
}
catch (InterruptedException
| ExecutionException e) {
e.printStackTrace();
}
List<Activity> gfgActs = new ArrayList<>();
gfgActs.addAll(gfgLikes);
gfgActs.addAll(gfgPOsts);
gfgActs.addAll(comments);
gfgActs.addAll(gfgCourses);
Collections.sort(
gfgActs,
(activity1, activity2)
-> activity1.getCreatedAt().compareTo(
activity2.getCreatedAt()));
callback.onResult(gfgActs);
});
}
private Callable<List<Like> > getGfgLikes(String url)
{
return () ->
{
System.out.println("getGfgLikes");
Thread.sleep(200);
return Arrays.asList(
new Like(new Date(1534334348560L)),
new Like(new Date(1554365436546960L)));
};
}
private Callable<List<Post> > getGfgPOsts(String url)
{
return () ->
{
System.out.println("getGfgPOsts");
Thread.sleep(500);
return Arrays.asList(
new Post(new Date(15334343448560L)),
new Post(new Date(153343434460L)));
};
}
private Callable<List<Comment> > getComments(String url)
{
return () ->
{
System.out.println("getComments");
Thread.sleep(200);
return Arrays.asList(
new Comment(new Date(15356565648560L)),
new Comment(new Date(151454545456460L)));
};
}
private Callable<List<Friend> >
getGfgCourses(String url)
{
return () ->
{
System.out.println("getGfgCourses");
Thread.sleep(6500);
return Arrays.asList(
new Friend(new Date(1534543354248560L)),
new Friend(new Date(15334343546460L)));
};
}
}
Executor
An object that executes Runnable tasks that have been submitted. This interface allows you to decouple task submission from the mechanics of how each task will be executed, such as thread usage, scheduling, and so on. Instead of explicitly creating threads, an Executor is typically used. Instead of invoking new Thread(new(RunnableTask())), for example. start() for each task in a sequence. It is, as the name implies, a thread pool with a fixed number of threads. The tasks submitted to the executor are executed by the n threads, and any additional tasks are stored on a LinkedBlockingQueue. It employs a Blocking Queue.
Creating and Running a Simple Executor, in which we will create a task and run it in a fixed pool.
- The Task class implements Callable and has a String parameter. It is also stated that it will throw an exception.
- To execute a task in the class "Task," we must first instantiate the Task class and pass it to the executor for execution.
- The Future object's result should be printed and displayed.
Similar Reads
Calling an External Program in Java using Process and Runtime
Java contains the functionality of initiating an external process - an executable file or an existing application on the system, such as Google Chrome or the Media Player- by simple Java code. One way is to use following two classes for the purpose: Process class Runtime class The Process class pres
2 min read
Difference Between Callable and Runnable in Java
java.lang.Runnable is an interface that is to be implemented by a class whose instances are intended to be executed by a thread. There are two ways to start a new Thread â Subclass Thread and implement Runnable. There is no need of sub-classing Thread when a task can be done by overriding only run()
3 min read
Multi-threaded Chat Application in Java | Set 2 (Client Side Programming)
Prerequisites : Introducing threads in socket programming, Multi-threaded chat Application | Set 1 This article gives the implementation of client program for the multi-threaded chat application. Till now all examples in socket programming assume that client first sends some information and then ser
5 min read
Asynchronous Programming and Kotlin Coroutines in Android
Asynchronous programming is very important and it's now a common part of modern application. It increases the amount of work that an app can execute by allowing tasks to execute in parallel. This makes sure that heavy tasks run in the background, keeping the UI thread responsive and improving the ov
4 min read
What does start() function do in multithreading in Java?
We have discussed that Java threads are typically created using one of the two methods : (1) Extending thread class. (2) Implementing RunnableIn both the approaches, we override the run() function, but we start a thread by calling the start() function. So why don't we directly call the overridden ru
2 min read
Multi-threaded chat Application in Java | Set 1 (Server Side Programming)
Prerequisites : Introducing threads in socket programmingIn the above article, a simple date time server was created which handled multiple user requests at the same time using threading. It explains the basic concepts of threading in network programming. The same concepts can be used with very slig
5 min read
Callable and Future in Java
Prerequisite: Threads, Multi-threading The need for Callable There are two ways of creating threads â one by extending the Thread class and other by creating a thread with a Runnable. However, one feature lacking in  Runnable is that we cannot make a thread return result when it terminates, i.e. whe
6 min read
MultiThreading in Android with Examples
Working on multiple tasks at the same time is Multitasking. In the same way, multiple threads running at the same time in a machine is called Multi-Threading. Technically, a thread is a unit of a process. Multiple such threads combine to form a process. This means when a process is broken, the equiv
3 min read
Difference Between Daemon Threads and User Threads In Java
In Java, there are two types of threads: Daemon ThreadUser Thread Daemon threads are low priority threads which always run in background and user threads are high priority threads which always run in foreground. User Thread or Non-Daemon are designed to do specific or complex task where as daemon th
4 min read
Difference between Multiprogramming and Multitasking
Both multi-programming and multi-tasking are related to concepts in operating systems. CPU is a super fast device and keeping it occupied for a single task is never a good idea. Considering the huge differences between CPU speed and IO speed, many concepts like multiprogramming, multitasking, multit
4 min read