Book Image

Concurrent Patterns and Best Practices

By : Atul S. Khot
Book Image

Concurrent Patterns and Best Practices

By: Atul S. Khot

Overview of this book

Selecting the correct concurrency architecture has a significant impact on the design and performance of your applications. Concurrent design patterns help you understand the different characteristics of parallel architecture to make your code faster and more efficient. This book will help Java developers take a hands-on approach to building scalable and distributed apps by following step-by-step explanations of essential concepts and practical examples. You’ll begin with basic concurrency concepts and delve into the patterns used for explicit locking, lock-free programming, futures, and actors. You’ll explore coding with multithreading design patterns, including master, slave, leader, follower, and map-reduce, and then move on to solve problems using synchronizer patterns. You'll even discover the rationale for these patterns in distributed and parallel applications, and understand how future composition, immutability, and the monadic flow help you create more robust code. By the end of the book, you’ll be able to use concurrent design patterns to build high performance applications confidently.
Table of Contents (14 chapters)

Race conditions


Let's start by looking at some concurrency bugs. Here is a simple example of incrementing a counter:

public class Counter {
  private int counter;

  public int incrementAndGet() {
    ++counter;
    return counter;
}

This code is not thread-safe. If two threads are running using the same object concurrently, the sequence of counter values each gets is essentially unpredictable.  The reason for this is the ++counter operation. This simple-looking statement is actually made up of three distinct operations, namely read the new value, modify the new value, and store the new value:

      

   

As shown in the preceding diagram, the thread executions are oblivious of each other, and hence interfere unknowingly, thereby introducing a lost update. 

The following code illustrates the singleton design pattern. To create an instance of LazyInitializationis expensive in terms of time and memory. So, we take over object creation. The idea is to delay the creation till its first use, and then...