How do I modify an int atomically and thread-safely in Java?
Atomically increment, test & set, etc...?
The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors.
Interlock. Exchange returns the original value while performing an atomic operation. The whole point is to provide a locking mechanism. So it is actually two operations: read original value and set new value.
Use AtomicInteger.
Thread safety can be achieved via synchronized functions. Wrap your int (or such data) in a class which provides the required functionalities via synchronized methods, e.g.
public class X
{
protected int x;
public synchronized void set( int value )
{
x = value;
}
}
You can also use classes from the java.util.concurrent.atomic package, e.g. AtomicInteger or AtomicIntegerArray
I just wanted to be sure to point out exactly what is wrong with this answer, in case anyone things that synchronized
can be used to solve thread race effects
| Thread A | Thread B |
|---------------|------------------|
| read x (x=4) | |
| | read x (x=4) |
| Calculate 4+1 | |
| EAX ← 5 | |
| | Calculate 4+1 |
| | EAX ← 5 |
| Start sync | |
| { | Start sync |
| { x ← 5 | wait |
| { | wait |
| End sync | wait |
| | { |
| | { x ← 5 |
| | { |
| | End sync |
The end result of the operations:
x = 4;
x += 1;
x += 1;
is that x = 5 rather than 6.
The same issue exists with the volatile
keyword. The volatile
keyword doesn't save you from thread effects. The volatile keyword only ensures that
Strictly speaking, volatile
ensures that memory operations are not reordered around a volatile variable. Which means you still suffer from the:
problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With