Java - Thread Executor Framework

Introduction

A task is a logical unit of work represented as a Runnable.

You can create a class to represent a task.

class MyTask implements Runnable {
        public void run() {
           // Task processing logic goes here
        }
}

You create tasks as follows:

MyTask task1 = new MyTask();
MyTask task2 = new MyTask();
MyTask task3 = new MyTask();

The Executor framework separates task submission from task execution.

You create a task and submit it to an executor.

The executor takes care of the execution details of the task.

It provides configurable policies to control many aspects of the task execution.

Executor interface from java.util.concurrent package is the main class for the executor framework.

It has only one method, as shown:

public interface Executor {
        void execute (Runnable command);
}

You can use the executor framework to execute the three tasks as follows:

Executor executor = Executors.newCachedThreadPool();
// Submit three tasks to the executor
executor.execute(task1);
executor.execute(task2);
executor.execute(task3);

You can choose to run all tasks in one thread, in a fixed number of threads, or in a variable number of threads.

You can use a thread pool to execute your tasks.

The commonly used methods of the Executors class to get an executor:

  • newCachedThreadPool() returns an ExecutorService object.
  • newFixedThreadPool(int nThreads) returns an ExecutorService with fixed number of threads.
  • newSingleThreadExecutor() returns an ExecutorService with one thread to execute all tasks.

You can instantiate the ThreadPoolExecutor class and configure the thread pool.

The following code shows how to use an executor.

Demo

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

class SubTask implements Runnable {
  private int taskId;
  private int loopCounter;

  public SubTask(int taskId, int loopCounter) {
    this.taskId = taskId;
    this.loopCounter = loopCounter;
  }// w w w.  j a  v a  2  s  .c  om

  public void run() {
    for (int i = 1; i <= loopCounter; i++) {
      try {
        int sleepTime = 3;
        System.out.println("Task #" + this.taskId + " - Iteration #" + i
            + " is going to sleep for " + sleepTime + " seconds.");
        Thread.sleep(sleepTime * 1000);
      } catch (Exception e) {
        System.out.println("Task #" + this.taskId + " has been interrupted.");
        break;
      }
    }
  }
}

public class Main {
  public static void main(String[] args) {
    int THREAD_COUNT = 3;
    int LOOP_COUNT = 3;
    int TASK_COUNT = 5;

    ExecutorService exec = Executors.newFixedThreadPool(THREAD_COUNT);
    for (int i = 1; i <= TASK_COUNT; i++) {
      SubTask task = new SubTask(i, LOOP_COUNT);
      exec.submit(task);
    }
    exec.shutdown();
  }
}

Result

Related Topics