Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Atomic Variables | High-level Synchronization Mechanisms
Multithreading in Java
course content

Conteúdo do Curso

Multithreading in Java

Multithreading in Java

1. Multithreading Basics
2. Synchronized Collections
3. High-level Synchronization Mechanisms
4. Multithreading Best Practices

Atomic Variables

We’ve already covered what atomicity is and the problems it can cause in the first section of this course. Back then, we addressed the issue using synchronized blocks or methods. Now, we’ll explore how to achieve the same result more easily by using an atomic class.

What are Atomic Variables?

Atomic variables ensure that operations (read, write, increment) on variables are performed atomically, meaning they are executed contiguously and safely in a multithreaded environment. This guarantees that the operation will be completed entirely, without the possibility of interference from other threads during its execution.

Why do We Need Atomic Variables?

Without the use of atomic variables or other synchronization mechanisms, operations like increment (++) can be unsafe. For instance, when multiple threads access the same variable simultaneously, updates might be lost, resulting in incorrect results. Atomic variables solve this problem by ensuring that operations on them are executed sequentially.

We previously discussed this issue when the increment operation was broken down into three steps (read, increment, write), but with atomic variables, it’s all done in one operation!

Types of Atomic Variables in Java

Note

In general, there are many atomic implementations, and we won’t cover them all here, as it would take too long.

Java provides several atomic variable classes in the java.util.concurrent.atomic package, each designed to handle a specific data type:

  • AtomicInteger: for atomic operations on int;
  • AtomicLong: for atomic operations on long;
  • AtomicBoolean: for atomic operations on boolean;
  • AtomicReference<V>: for atomic operations on objects (generic type).

Methods

The get() method returns the current value of a variable. The set(V newValue) method sets a new value for the variable. On the other hand, lazySet(V newValue) is similar to set(), but it can defer updating the value, offering an ordered update in certain situations.

java

Main

The compareAndSet(V expect, V update) method updates the value if the current value matches the expected value. It returns true if the update was successful, and false if the current value did not match the expected value. In contrast, the getAndSet(V newValue) method sets a new value and returns the previous value.

java

Main

The getAndIncrement() and getAndDecrement() methods increment or decrement the current value by one and return the previous value. These methods apply to numeric atomic variables such as AtomicInteger and AtomicLong. In contrast, the incrementAndGet() and decrementAndGet() methods also increment or decrement the current value by one but return the new value.

java

Main

The getAndAdd(int delta) method adds the specified value (delta) to the current value and returns the previous value. This method is used with numeric atomic variables. On the other hand, the addAndGet(int delta) method also adds the specified value (delta) to the current value but returns the new value.

java

Main

Examples of Using Atomic Variables

Example with AtomicInteger (AtomicLong, AtomicBoolean are the same, so there will be no separate examples for them).

Task: To implement a counter that is safely incremented by several threads.

java

Main

As you can see we didn't use any synchronization here, as the atomic variable itself provides this function

This example uses AtomicInteger to safely increment the counter. The getAndIncrement() method first returns the current value of the variable, then increments it by one. This happens atomically, ensuring that the variable is updated correctly.

Example with AtomicReference

Task: Provide atomic updating of a reference to an object.

java

Main

AtomicReference is used here to atomically update the value of a string reference. The getAndSet() method atomically sets the new value and returns the previous value.

Note

Unlike regular variables, which require additional *synchronization, atomic variables utilize low-level primitives to minimize overhead and enhance performance. This makes them particularly well-suited for high-concurrency systems.

1. What is the advantage of using atomic variables in multithreaded programming?
2. Which atomic variable method provides an atomic change in value if the current value is the same as the expected value?
3. What does the set() method guarantee in atomic variables?

What is the advantage of using atomic variables in multithreaded programming?

Selecione a resposta correta

Which atomic variable method provides an atomic change in value if the current value is the same as the expected value?

Selecione a resposta correta

What does the set() method guarantee in atomic variables?

Selecione a resposta correta

Tudo estava claro?

Seção 3. Capítulo 5
We're sorry to hear that something went wrong. What happened?
some-alt