Posted by Marta on February 2, 2023 Viewed 2366 times
In this article you will learn what is a runnable , what is a callable and the difference between the two in java, runnable vs callable. These concepts are important when you are dealing with concurrency.
Concurrency basically means there is not just one execution thread in your program, but several executions or threads, potentially happening simultaneously. Therefore different pieces of the code might be executed at the same time.
To illustrate the runnable and callable concepts I have included several examples throughout the article. Let’s get started!
The Runnable interface in java enables you to define a block of code that can be executed within its own thread. Therefore if you create several runnable classes and execute them, and you will have several threads running at the same time within the same process or program. This is known as concurrency.
See the runnable interface below:
public interface Runnable { public abstract void run(); }
You can think of runnable as a wrapper class that allow you to define a piece of code that can be executed in isolation. Consequently this task could run in parallel with other tasks.
For example, let’s say you are cooking a rice recipe and you need to chop vegetables and boil rice. You can do these two tasks one after the other one. However if you can do both at the same time, in parallel, you will finish much faster. That’s what runnable allow you to do in java. Define code as isolated task and execute them in parallel. Also runnable allow you to run tasks in the background, to avoid blocking the main execution thread.
To illustrate how the runnable interface works, see the below examples:
public class WorkRunnable implements Runnable{ @Override public void run() { try { System.out.println("Task started"); Thread.sleep(1000); String name = Thread.currentThread().getName(); String state = Thread.currentThread().getState().toString(); System.out.println("Thread "+name+" with state "+state); } catch (InterruptedException e) { e.printStackTrace(); } } }
The code above is quite simple. This runnable class will print Task started
to the console. Then wait for one second. And last it will print the name of the thread that has executed the task.
Next is callable. Callable is also a java interface and as Runnable, you can use it to run tasks in parallel. However there is a key difference. The callable can return the result of the task or throw an exception.
public interface Callable<V> { V call() throws Exception; }
The Callable interface is included in Java to address some of runnable limitations. Let’s say your program is executing a long calculation task defined as a runnable. And you would like to retrieve the calculation result. Since the runnable interface is defined to return void
, in other words nothing, you can’t pass back the calculation result directly. You will need to use shared data structure for this purpose. The callable interface solves this problem.
To illustrate how to use Callable, let’s see an example.
public class WorkCallable implements Callable<String>{ @Override public String call() throws Exception{ try { System.out.println("Task started"); Thread.sleep(1000); String name = Thread.currentThread().getName(); String state = Thread.currentThread().getState().toString(); System.out.println("Thread "+name+" with state "+state); } catch (InterruptedException e) { e.printStackTrace(); } return "Task done"; } }
The code above is basically doing the same as the previous example: printing Task started
, waiting for 1 second and lastly printing the thread name. But there is one key different, when you implement the class you have to specify the type of the returning variable. In this example the Callable
will return a string, however it could return any type you want, included a class you defined.
Let’s see another example of the Callable
interface. In this example, I will modify the class WorkCallable
so instead of waiting 1000 ms, It will wait for any number of milliseconds that I pass in. To do so, I will add a variable field and a constructor to the WorkCallable
class.
public class WorkCallable implements Callable<String> { private int millisecondToWait; public WorkCallable(int millisecondToWait){ this.millisecondToWait = millisecondToWait; } @Override public String call() throws Exception{ try { System.out.println("Task started: Waiting for " + millisecondToWait); Thread.sleep(millisecondToWait); String name = Thread.currentThread().getName(); String state = Thread.currentThread().getState().toString(); System.out.println("Thread "+name+" with state "+state); } catch (InterruptedException e) { e.printStackTrace(); } return "Task done"; } }
This demonstrates a way of passing input values to the Callable
task. This same method can be applied for Runnable
as well. This can be useful if you want to define an isolated or independent task that needs depends on some input values. You could see those values as parameter to the Runnable
.
The main difference between Runnable
and Callable
is that Callable
will return the result of executing the task to the caller. If you use Runnable
you can’t return anything, any result will need to be saved in separated shared structure or database. To understand this difference runnable vs callable, you can compare the two interfaces.
public interface Runnable { public abstract void run(); } public interface Callable<V> { V call() throws Exception; }
You know to create a Runnable
class. You just need to create a class that implement the Runnable
interface. And then fill up the run
method with the code snippet that you want to run in a different thread. This will define our task. Now let’s see how to execute the runnable. There are a few ways, using our previous example.
First way is creating an instance of the Runnable
class and then call the run
method. This will run the code in the main application thread.
new WorkRunnable().run(); System.out.print("End");
Output:
Task started Thread main with state RUNNABLE End
As you can see in the code above, the Runnable
will finish executing and the next line System.out.print("End");
will be executed. Both statements are executed sequentially because they are executed by one single thread. In this case, the main thread will be blocked and the program is not using concurrency.
Let’s see how to execute the Runnable
class in a separated thread.
new Thread(new WorkRunnable()).start(); System.out.println("End");
Output:
Task started End Thread Thread-0 with state RUNNABLE
As you can see the thread name is different now. This means the program has created a different execution thread to execute the code contained in the WorkRunnable
class. The main thread will trigger the runnable and then continue with the execution. That’s why the text end
is printed before the runnable finished its execution.
Just like a Runnable
, you can execute a Callable
in a few different ways.
You can execute it in the main thread, which will blocked the main thread until the Callable
execution finished. See how it works below:
new WorkCallable(1000).call(); System.out.println("End");
Output:
Task started: Waiting for 1000 Thread main with state RUNNABLE End
You can run the Callable
in a separate thread. This way won’t block the main thread. However the way to execute a Callable
in a separated thread is slightly different than the Runnable
way. In this case you will create a thread pool. This thread will be idle until you submit a task to the pool. As soon as you submit the task, the pool will find a thread idle and it will execute the task. See this in action below:
ExecutorService pool = Executors.newCachedThreadPool(); pool.submit(new WorkCallable(1000)); System.out.println("End");
Output:
End Task started: Waiting for 1000 Thread pool-1-thread-1 with state RUNNABLE
To summarise, in this article we have covered how Runnable
and Callable
interfaces in java enable you to define code snippet that you can execute in different threads. This allow you to take advantage of the concurrency framework that java provides. Additionally we have seen the different between a Callable
and a Runnable
, runnable vs callable, and how to execute each of them.
I hope you enjoy the article and thank you so much for reading and supporting this blog! 🙂
Matplotlib guide : Custom a graph – Imshow, Colorbar, etc
Django: order by and filter with examples
What is the use of return in python programming?
Steady pace book with lots of worked examples. Starting with the basics, and moving to projects, data visualisation, and web applications
Unique lay-out and teaching programming style helping new concepts stick in your memory
Great guide for those who want to improve their skills when writing python code. Easy to understand. Many practical examples
Perfect Boook for anyone who has an alright knowledge of Java and wants to take it to the next level.
Excellent read for anyone who already know how to program and want to learn Best Practices
Perfect book for anyone transitioning into the mid/mid-senior developer level
Great book and probably the best way to practice for interview. Some really good information on how to perform an interview. Code Example in Java