In Java, atomic variables and operations used in concurrency. The multi-threading environment leads to a problem when concurrency is unified. The shared entity such as objects and variables may be changed during the execution of the program. Hence, they may lead to inconsistency of the program. So, it is important to take care of the shared entity while accessing concurrently. In such cases, the atomic variable can be a solution to it. In this section, we will discuss atomic classes, atomic variables, atomic operations, along with examples.
Before moving ahead in this section, ensure that you are aware of thread, synchronization, and lock in Java.
Java Atomic Classes
Java provides a java.util.concurrent.atomic package in which atomic classes are defined. The atomic classes provide a lock-free and thread-safe environment or programming on a single variable. It also supports atomic operations. All the atomic classes have the get() and set() methods that work on the volatile variable. The method works the same as read and writes on volatile variables.
The package provides the following atomic classes:
Objects of these classes represent the atomic variable of int, long, boolean, and object reference respectively. The atomic classes have some common methods are as follows:
Those operations that always execute together is known as the atomic operations or atomic action. All the atomic operations either execute effectively happens all at once or it does not happen at all. Three key concepts are associated with atomic actions in Java are as follows:
1. Atomicity deals with which actions and sets o actions have invisible For example, consider the following code snippet:
In the above code, the behavior of running increment() and decrement() concurrently is undefined and not predictable.
2. Visibility determines when the effect of one thread can be seen by another. For example, consider the following code snippet:
In the above code, it is possible that thread T2 will never stop even after thread T1 sets done to true. Also, not that there is no synchronization between threads.
3. Ordering determines when actions in one thread occur out of order with respect to another thread.
The order that fields a and b appear in thread T2 may differ from the order they were set in Thread T1.
Let's understand it through an example.
In the above code snippet, we have declared an int type variable count and inside the method incrementCount() assigned it to 1. In such a case, either all happen together or would not happen at all. Hence, it represents an atomic operation and the operation is known as atomicity.
Let's consider another code snippet.
It seems that it is also an atomic operation but not so. It is a linear-operation that consists of three operations i.e. read, modify, and write. Therefore, it can execute partially. But if we are using the above code in a multi-threaded environment, it creates a problem.
Suppose, we have called the above code in a single-threaded environment, the updated value of count will be 2. If we call the above method by two separate threads, they both access the variable at the same time and also update the value of count simultaneously. To avoid this situation, we use atomic operation.
Java supports several types of atomic actions, are as follows:
Let's see how can we create an atomic operation.
The atomic variable allows us to perform an atomic operation on a variable. Atomic variables minimize synchronization and help avoid memory consistency errors. Hence, it ensures synchronization.
The atomic package provides the following five atomic variables:
The Need of Atomic Variable
Let's consider the following code.
The above program gives the expected output if it is executed in a single-threaded environment. A multi-threaded environment may lead to unexpected output. The reason behind it that when two or more threads try to update the value at the same time then it may not update properly.
Java offers two solutions to overcome this problem:
Let's create a Java program and use an atomic variable to overcome the problem.
By using Atomic Variable
Synchronized Vs. Atomic Vs. Volatile