Monday, November 23, 2020

Difference between a Thread and an Executor in Java

Even though both Thread and Executor, both are used to execute some code in parallel, there are some key differences between them. The main difference between a Thread and an Executor in Java is that it later provides a thread pool in Java. Along with several concurrency utilities like CountDownLatch, CyclicBarrier, Semaphore, FutureTask, Callable interface, and Conditions, JDK 5 also introduced a built-in thread pool, which provides a set of working threads to run your code in parallel. Since creating, starting, and running a thread is a time-consuming and expensive operation, many Java applications create a spool of thread at start-up and leverage that for executing the task in parallel until Java introduced the built-in thread pool.

This thread-pool is known as the Executor framework which relieved Java application developers from the responsibility of creating and managing threads

The JDK 1.5 Executor framework is a combination of Executor, Executors, and ExecutorService interface to provide a fully functional, feature-rich thread pool in Java.  By the way that was the fundamental difference between the Thread and Executor concept in Java, let's see a couple of more details about Thread and Executor to answer this question better.

And, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at the Java Multithreading, Concurrency, and Performance Optimization course by Michael Pogrebinsy on Udemy. It's an advanced course to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance.





Thread vs Executor in Java 

As I said, a Thread is used to run your code in parallel and you can create and start your own thread either by extending java.lang.Thread class or implementing java.lang.Runnable interface. Though both approaches work well in small applications, they have their pros and cons, which you can see here. 

On the other hand, Executor is an interface which also provides parallel execution, but via a thread pool, which is more suitable for large Java application.

1) The first and foremost difference between Thread and Executor is that java.lang.Thread is a class in Java while java.util.concurrent.Executor is an interface.


2) The Executor concept is actually an abstraction over parallel computation. It allows concurrent code to be run in a managed way. On the other hand, Thread is a concrete way to run the code in parallel.

3) The third difference between an Executor and a Thread class is that the former decouples a task (the code which needs to be executed in parallel) from execution, while in the case of a Thread, both task and execution are tightly coupled.  You can further check the Applying Concurrency and Multi-threading to Common Java Patterns course by Jose Paumard, a Java Champion on Pluralsight to learn more about how decoupling a task from execution simplify the design of concurrent applications in Java.

4) The Executor concept allows your task is to be executed by a worker thread from the thread pool, while Thread itself execute your task.

Difference between a Thread and an Executor in Java

5) Executor provides a execute() method which accepts a Runnable task, while Thread accepts the Runnable task on its constructor.

6) One more key difference between a Thread and an Executor is that a Thread can only execute one Runnable task but an Executor can execute any number of Runnable tasks.

7) In the case of Thread, the task is executed by the Thread which accepts Runnable instance, but in the case of Execution the command (a Runnable implementation) may be executed in a new thread, a pooled thread, or in the calling thread itself, depending upon the implementation of Executor interface.

8) In the case of a thread, it's the developer's responsibility to create and start the thread, but in the case of Executor, the framework will create and start threads for you. Though you can control the whole process by giving your implementation of the Executor interface. 

Though, with the improvements in ForkJoinPool in Java 7 and 8, you might want to use that instead of Executor. If ForkJoinPool is a new concept to you, I suggest joining Multithreading and Parallel Computing in Java course on Udemy to learn more about it.

Difference between a Thread and an Executor in Java




7) Now, let's see an example of execution of a Runnable task via Executor and via Thread in Java:

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Main {

  public static void main(String args[]) {

    Runnable task = new Runnable() {
      @Override
      public void run() {
        System.out.println("Task is executed by : "
            + Thread.currentThread().getName());
      }
    };

    Thread t = new Thread(task, "MY_THREAD");
    t.start();

    Executor e = Executors.newSingleThreadExecutor();
    e.execute(task);

  }
}

Output
Task is executed by MY_THREAD
Task is executed by pool-1-thread-1

The difference is quite clear that first is just a thread while later is a pool of threads.

It's worth noting that factory methods of Executors class e.g. newSingleThreadExecutor() return an ExecutorService, which is a sub-interface of Executor and also provides methods to accepts a Callable, terminate, or shut down the thread pool.


That's all about the difference between a Thread and an Executor in Java. You can see that even though both are related to the parallel execution of tasks they are a separate abstraction. A Thread represents something which is responsible for executing your code in parallel, while an Executor is an abstraction for concurrent task execution. 

Most importantly, Executor decouples the task to its execution which means an asynchronous execution is possible, but task and execution are tightly coupled in the case of Thread.



Other multi-threading articles you may like
  • Top 50 Java Multithreading Interview Questions from last 5 years (list)
  • Top 5 Courses to learn Multithreading and Concurrency in Java (courses)
  • 10 Multithreading and Concurrency Best Practices Java developer should follow (article)
  • How to use Future and FutureTask in Java? (tutorial)
  • How to solve the Producer-Consumer Problem using Lock and Condition (solution)
  • Is "Java Concurrency in Practice" Still Valid in the era of Java 8? (opinion)
  • How to join more than two Threads in Java? (example)
  • What is the right way to stop a Thread in Java? (tutorial)
  • Top 10 Courses to learn Java in-depth (courses)
  • Difference between extends Thread and implements Runnable in Java? (answer)
  • Top 5 courses to Learn Java Performance Tuning (courses)
  • Difference between the start() and run() method of Thread in Java? (answer)
  • 10 Courses to Crack Java Interviews for Beginners (courses)
  • Top 12 Java Concurrency Questions for Experienced Programmers (see here)
  • Difference between multi-threading and multi-tasking in Java? (answer)
  • Top 5 Books to learn Java Concurrency in-depth (books)
  • What is happens-before in Java Concurrency? (answer)
  • 6 Books to learn Multithreading and Concurrency in Java (books)
  • 10 Advanced Core Java Courses for Experienced programmers (course)

Thanks for reading this article. If you like this article about Thread vs Executor in Java then please share it with your friends and colleagues. If you have any suggestions or feedback then please drop a comment. 

P. S. - If you are new to Java Programming language and want to learn multithreading concepts looking for some free courses to start with then you can also check out this free Java Multithreading course on Udemy. It is a fantastic free online course to learn  Java Multithreading from scratch as well.

5 comments :

Unknown said...

Far from easy

Unknown said...

e.shutdown(); should be called at the end, otherwise this program will never stop...

Unknown said...

here is a slightly modified version of the program that exits after the thread has completed execution.

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class th_vs_ex {

public static void main(String[] args) {

Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("task info: " + Thread.currentThread().getName());
}
};


Thread t = new Thread(task);
t.start();

ExecutorService x = Executors.newSingleThreadExecutor();
x.execute(task);

x.shutdown();
}

}

Unknown said...

the interface java.util.concurrent.ExecutorService and not java.util.concurrent.Executor contains the method shutdown().

javin paul said...

Thanks Strikr, that's correct.

Post a Comment