如何在Java中以原子性和线程安全的方式修改一个int?
原子性地增加、测试和设置等操作?
如何在Java中以原子性和线程安全的方式修改一个int?
原子性地增加、测试和设置等操作?
通过同步函数可以实现线程安全。 将您的 int(或类似数据)封装在一个类中,该类通过同步方法提供所需的功能,例如:
public class X
{
protected int x;
public synchronized void set( int value )
{
x = value;
}
}
您还可以使用java.util.concurrent.atomic包中的类,例如AtomicInteger或AtomicIntegerArray。
我只是想确保指出这个答案的问题所在,以防有人认为synchronized
可以用来解决线程竞争效应。
| 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 |
x = 4;
x += 1;
x += 1;
这意味着x = 5而不是6。
volatile
关键字也存在同样的问题。 volatile
关键字不能保护你免受线程影响。 volatile
关键字只确保:
严格来说,volatile
确保内存操作不会在volatile变量周围重新排序。 这意味着您仍然会遇到以下问题:
的问题。
private final static AtomicInteger at = new AtomicInteger();
public void run() {
at.set(7);
int i = at.incrementAndGet();