Java Concurrency - Part 2: High Level Concurrency Objects

Gökhan Kanber
3 min readFeb 11, 2021
Andromeda

This article is a part of the Java Programming Language article series.

High Level Concurrency Objects

  • Lock Objects
  • Executors
  • Concurrent Collections
  • Atomic Variables
  • Concurrent Random Numbers

Lock Objects

  • The java.util.concurrent.locks package
  • The Lock interface
  • The biggest advantage of Lock objects over implicit locks is their ability to back out of an attempt to acquire a lock
  • The tryLock method backs out if the lock is not available immediately or before a timeout expires if specified
  • The lockInterruptibly method backs out if another thread sends an interrupt before the lock is acquired

Executors

  • A high-level API for launching and managing threads
  • The java.util.concurrent packages
  • Executor Interfaces
  • Thread Pools
  • Fork/Join

Executor Interfaces

  • Executor: a simple interface to launch new tasks
  • ExecutorService: a subinterface of Executor with new features to manage the lifecycle of tasks and executor
  • ScheduledExecutorService: a subinterface of ExecutorService that supports future and periodic execution of tasks

The Executor Interface

  • The execute method
  • Accepts a Runnable object

The ExecutorService Interface

  • The submit method
  • Accepts a Runnable and Callable objects
  • Callable object allows the task to return a value
  • Returns a Future object to retrieve the Callable return value and to manage the status of the task

The ScheduledExecutorService Interface

  • The schedule method
  • Executes a Runnable or Callable task after a specified delay
  • The scheduleAtFixedRate and scheduleWithFixedDelay methods execute specified tasks repeatedly at defined intervals

Thread Pools

  • Consist of worker threads
  • Used by most of the executor implementations
  • Exists separately from the Runnable and Callable tasks
  • Minimizes the memory management overhead due to thread creation

The fixed thread pool

  • Has a specified number of threads running
  • If a thread is terminated while it is still in use, it is automatically replaced with a new thread
  • Tasks are submitted to the pool via an internal queue, which holds extra tasks whenever there are more active tasks than threads
  • The newFixedThreadPool factory method in Executors class

Executors class methods

  • The newCachedThreadPool method creates an executor with an expandable thread pool, suitable for applications that launch many short-lived tasks
  • The newSingleThreadExecutor method creates an executor that executes a single task at a time
  • The ScheduledExecutorService versions of these methods

For additional options, construct instances of java.util.concurrent.ThreadPoolExecutor or java.util.concurrent.ScheduledThreadPoolExecutor

Fork/Join

  • The fork/join framework is an implementation of the ExecutorService interface
  • To use all the available processing power to enhance the performance of your application
  • Distributes tasks to worker threads in a thread pool, as with any ExecutorService implementation
  • The center of the fork/join framework is the ForkJoinPool class, an extension of the AbstractExecutorService class
  • ForkJoinPool implements the core work-stealing algorithm and can execute ForkJoinTask processes
  • Work-stealing algorithm: worker threads that run out of things to do can steal tasks from other threads that are still busy

Pseudocode for Basic Use

  • Write code that performs a segment of the work
  • Wrap this code in a ForkJoinTask subclass, RecursiveTask (which can return a result) or RecursiveAction
  • Call the invoke method of a ForkJoinPool instance with the task objects

Blurring an Image

Run

Standard Implementations

  • The features that are implemented using the fork/join framework
  • The parallelSort method in the java.util.Arrays class
  • The methods in the java.util.streams package

Concurrent Collections

  • The java.util.concurrent package
  • Defines a happens-before relationship between an operation that adds an object to the collection with subsequent operations that access or remove that object to avoid memory consistency errors

BlockingQueue

  • A first-in-first-out data structure
  • Blocks or times out when you attempt to add to a full queue, or retrieve from an empty queue

ConcurrentMap

  • A subinterface of java.util.Map
  • Defines useful atomic operations
  • The standard general-purpose implementation is ConcurrentHashMap
  • A concurrent analog of HashMap

ConcurrentNavigableMap

  • A subinterface of ConcurrentMap
  • Supports approximate matches
  • The standard general-purpose implementation is ConcurrentSkipListMap
  • A concurrent analog of TreeMap

Atomic Variables

  • The java.util.concurrent.atomic package
  • Classes that support atomic operations on single variables
  • The get and set methods work like reads and writes on volatile variables
  • A set has a happens-before relationship with any subsequent get on the same variable
  • The atomic compareAndSet method also has these memory consistency features

Simple counter

Synchronized counter

  • Thread interference and liveness problems

Atomic counter

Concurrent Random Numbers

  • The java.util.concurrent.ThreadLocalRandom class
  • To use random numbers from multiple threads or ForkJoinTasks

--

--