Reputation: 230038
How do I modify an int atomically and thread-safely in Java?
Atomically increment, test & set, etc...?
Upvotes: 16
Views: 9515
Reputation: 4153
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 thinks 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.
Upvotes: 1
Reputation: 10900
private final static AtomicInteger at = new AtomicInteger();
public void run() {
at.set(7);
int i = at.incrementAndGet();
Upvotes: 0