如何在Java中原子地和线程安全地修改int?
原子增量,测试&等等......?
答案 0 :(得分:28)
答案 1 :(得分:1)
可以通过同步功能实现线程安全。 将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变量周围重新排序。这意味着您仍然受到以下情况的影响:
问题。
答案 2 :(得分:0)
private final static AtomicInteger at = new AtomicInteger();
public void run() {
at.set(7);
int i = at.incrementAndGet();