Difference between a Thread and an Executor in Java

Even though both Thread and Executor, both are used to executed some code in parallel, there are some key differences between them.The main difference between a Thread and an Executor in Java is that 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 built-in thread pool, which provides 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 pool 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 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 Thread and Executor concept in Java, let's see a couple of more details about Thread and Executor to answer this question better.




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 application, 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) 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 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 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 read Java Concurrency in Practice by Brian Goetz 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 task.

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 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 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 reading Java 8 in Action to learn more about it.

Thread vs Executor in Java


7) Now, let's see an example of execution 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 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 task 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 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)
  • 10 Multithreading and Concurrency Best Practices Java developer should follow (article)
  • How to use Future and FutureTask in Java? (tutorial)
  • How to solve 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)

Further Learning
Java Fundamentals Part 1,2
Java Concurrency in Practice
Applying Concurrency and Multi-threading to Common Java Patterns

2 comments :

Hesham Fas said...

Far from easy

Sebastian Mielcarek said...

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

Post a Comment