Java Concurrency Tutorial

In this tutorial, we will learn high-level concurrency features introduced with version 5.0 of the Java platform. Most of these features are implemented in the new java.util.concurrent packages.

In previous tutorial Java Multithreading Tutorial, we have learned low-level APIs that have been part of the Java platform from the very beginning. These APIs are adequate for very basic tasks.In this tutorial, we only focus on high-level concurrency features Executor framework introduced with version 5.0 of the Java platform. If you want to learn basics then check out Java Multithreading Tutorial.With an executor, we only have to implement the Runnable objects and send them to the executor. The executor is responsible for their execution, instantiation, and running with necessary threads. But it goes beyond that and improves performance using a pool of threads. When you send a task to the executor, it tries to use a pooled thread for the execution of this task, to avoid continuous spawning of threads.Another important advantage of the Executor framework is the Callable interface. It's similar to the Runnable interface, but offers two improvements, which are as follows:1. The main method of this interface, named call(), may return a result.2. When you send a Callable object to an executor, you get an object that implements the Future interface. You can use this object to control the status and the result of the Callable object.Let's understand the Executor Framework in depth with all the interfaces and it's implementation.

Executor Interfaces

The java.util.concurrent package defines three executor interfaces:

Executor, a simple interface that supports launching new tasks.

ExecutorService, a subinterface of Executor, which adds features that help manage the lifecycle, both of the individual tasks and of the executor itself.

1. The Executor Interface

An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads. For example, rather than invoking new Thread(new(RunnableTask())).start() for each of a set of tasks, you might use:

In this article, we will learn the ExecutorService interface supplements execute with a similar, but more versatile submit method. Like execute, submit accepts Runnable objects, but also accepts Callable objects, which allow the task to return a value. The submit method returns a Future object, which is used to retrieve the Callable return value and to manage the status of both Callable and Runnable tasks. Read more on ExecutorService Interface in Java

In this article, the ScheduledExecutorService interface that can schedule commands to run after a given delay, or to execute periodically.

The schedule() methods create tasks with various delays and return a task object that can be used to cancel or check execution. The scheduleAtFixedRate() and scheduleWithFixedDelay() methods create and execute tasks that run periodically until cancelled.