Thread Congestion in Java

Jakob Jenkov
Last update: 2021-12-09

Thread congestion can occur when two or more threads are trying to access the same, guarded data structure at the same time. By "guarded" I mean that the data structure is guarded using synchronized blocks or a concurrent data structure (Lock, BlockingQueue etc.) so that the data structure is thread safe. The resulting thread congestion means that the threads trying to access the shared data structure are spending a high amount of time waiting in line to access the data structure - wasting valuable execution time on waiting.

A blocking queue with 4 threads accessing it - possibly causing thread congestion.

Thread Congestion Tutorial Video

If you prefer video I have a video version of this thread congestion tutorial here: Thread Congestion in Java

Thread Congestion in Java

Thread Blocking Data Structures May Cause Thread Congestion

A data structure which blocks threads from accessing it - depending on what other threads are currently accessing it - may cause thread congestion. If more than one thread accesses such a data structure at the same time, one or more of the threads may be queued up waiting to access the data structure.

This queuing up is not visible in your code. The queuing up happens inside the Java VM. Therefore thread congestion is not so easy to spot simply by looking at your code. You may need profiling tools to detect thread congestion - or, you need to learn where to predict thread congestion can occur.

A blocking queue with 4 threads accessing it - with the 3 consuming thread queued up to access the blocking queue.

A Blocked Thread Loses Execution Time

While a thread is blocked trying to execute a blocking data structure, it cannot do anything. Thus, while being blocked the thread loses possible execution time. The longer the thread is blocked, the more potential execution time it loses.

The More Threads - The Higher Congestion

The more threads that attempt to access a shared, blocking data structure, the higher the risk is of thread congestion occurring, and the higher the congestion may be (the number of threads queued up waiting to access the data structure).

Alleviating Thread Congestion

To alleviate thread congestion you must reduce the number of threads trying to access the blocking data structure at exactly the same time. There are several ways to do that.

Multiple Data Structures

One way to alleviate thread congestion - at least around blocking queues - is to give each consuming thread its own queue, and have the producing thread distribute the objects (e.g. tasks) among these blocking queues. This way, only 2 threads are ever accessing each queue: The producing thread and the consuming thread.

A producing thread distributing the produced objects among 3 queues - one for each consuming thread.

Non-blocking Concurrency Algorithms

Another way is to use non-blocking concurrency algorithms where the threads accessing the data structure are never blocked. Non-blocking concurrency algorithms and data structures can often waste less of the thread's potential execution time than blocking concurrency algorithm or data structure.

Jakob Jenkov

Featured Videos

Java ForkJoinPool

P2P Networks Introduction


Java Persistence
Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Next tutorial in this tutorial trail