What's Java's equivalent of .Net's Interlocked class?
-
18-09-2019 - |
Question
How do I modify an int atomically and thread-safely in Java?
Atomically increment, test & set, etc...?
Solution
Use AtomicInteger.
OTHER TIPS
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
Why this answer won't work
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
- caches are flushed before a variable is read
- caches are flushed after a value is written
Strictly speaking, volatile
ensures that memory operations are not reordered around a volatile variable. Which means you still suffer from the:
- read from x
- write to x
problem.
private final static AtomicInteger at = new AtomicInteger();
public void run() {
at.set(7);
int i = at.incrementAndGet();