Free tutorials for Java, Eclipse and Web programming



Follow me on twitter

Java Concurrency / Multithreading - Tutorial

Lars Vogel

Version 0.9

15.11.2009

Revision History
Revision 0.0.128.12.2008Lars Vogel
First DRAFT
Revision 0.212.01.2009Lars Vogel
Added Join-Fork
Revision 0.304.05.2009Lars Vogel
Concurrency moved to own article, restructed article
Revision 0.405.05.2009Lars Vogel
Thread Pools, Callable and Futures part of the article re-written
Revision 0.512.06.2009Lars Vogel
Added deadlock description
Revision 0.620.07.2009Lars Vogel
Example for synchronized
Revision 0.721.07.2009Lars Vogel
Defensive copy
Revision 0.801.11.2009Lars Vogel
Added nonblocking algorithm description
Revision 0.915.11.2009Lars Vogel
Added CAS explicit operation

Java Concurrency / Multithreading

This article describes how to do concurrent programming with Java. It covers the concepts of parallel programming, immutability, threads, the executor framework (thread pools), futures, callables and the fork-join framework.


Table of Contents

1. Concurrency
1.1. Overview
1.2. Process vrs. threads
1.3. Amdahl's Law
1.4. Concurrency issues
2. Concurrency in Java
2.1. Processes and Threads
2.2. Synchronized
2.3. Volatile
3. The Java memory model
3.1. Overview
3.2. Atomic operation
3.3. The "synchronized" keyword
3.4. The "volatile" keyword
4. Immutability and Defensive Copies
4.1. Immutability
4.2. Defensive Copies
5. Threads in Java
6. Threads pools with the Executor Framework
7. Futures and Callables
8. Nonblocking algorithms
9. Fork-Join in Java 7
10. Deadlock
11. Thank you
12. Questions and Discussion
13. Links and Literature
13.1. Source Code
13.2. Concurrency Resources
13.3. vogella Resources

1. Concurrency

1.1. Overview

Concurrency is the ability to run several parts of a program or several programs in parallel. Concurrency can highly improve the throw-put of a program if certain tasks can be performed asynchronously or in parallel.

Almost every computer nowadays has several CPU's or several cores within one CPU. The ability to leverage theses multi-cores can be the key for a successful high-volume application.

1.2. Process vrs. threads

The distinction between processes and threads is important.

  • Process: A process runs independently and isolated of other processes. It cannot directly access shared data in other processes. The resources of the process are allocated to it via the operating system, e.g. memory and CPU time.

  • Threads: threats are co called lightweight processes which have their own call stack but an access shared data. Every thread has its own memory cache. If a thread reads shared data it stores this data in its own memory cache. A thread can re-read the shared data, when this happens in Java will be explained in Java memory model part of this article.

Within a Java application you work with several threads to archive parallel processing or asynchronously behavior.

1.3. Amdahl's Law

Concurrency promises to perform certain task faster as these tasks can be divided into subtasks and these subtasks can be executed in parallel. Of course the runtime is limited by parts of the task which can be performed in parallel.The theoretical possible performance gain can be calculated by Amdahl's Law. If F is the percentage of the program which can not run in parallel and N is the number of processes then the maximum performance gain is 1/ (F+ ((1-F)/n)).

1.4. Concurrency issues

Threads have there own call stack but can also access shared data. Therefore you have two basic problems, visibility and access problems.

A visibility problem occurs if one thread reads shared data which is later changed by other thread and if thread A does not see this change.

A access problem occurs if several thread trying to access and change the same shared data at the same time.

Visibility and access problem can lead to

  • Liveness failure: The program does not react anymore due to problems in the concurrent access of data, e.g. deadlocks.

  • Safety failure: The program creates incorrect data.