Concurrency is the ability to run several parts of a program or several programs in parallel. Concurrency can highly improve the throughput 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 these multi-cores can be the key for a successful high-volume application.
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: threads are so 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 achieve parallel processing or asynchronous behavior.
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)).
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.