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)

The big lock approach 


Our first design, the big lock design, allows only one thread at a time! The following class illustrates this: 

public class BigLockHashSet<T> extends HashSet<T> {
final Lock lock;
final int LIST_LEN_THRESHOLD = 100;

public BigLockHashSet(int capacity) {
super(capacity);
lock = new ReentrantLock();
}

As shown in the preceding code, the class is a subclass of HashSet<T> and uses a ReentrantLock. As noted earlier, a reentrant lock is one that allows the owner thread to reacquire it. The LIST_LEN_THRESHOLD constant is used in theshouldResize()method that is described in the next section.

The lock() and unlock() methods are overridden, and they just ignore the x parameter. The methods are shown in the following code: 

@Override
protected void unlock(T x) {
lock.unlock();
}

@Override
protected void lock(T x) {
lock.lock();
}

As shown in the preceding code, this implementation just locks and unlocks the reentrant lock; it does not make any use of the element...