AtomicInteger与同步的getter / setter

时间:2012-03-21 21:10:50

标签: java multithreading concurrency

这个类是线程安全的吗?

是否可以看到不一致的值?让我们说最初的值为80.线程1调用setA(100)并进入函数但尚未调用a.set(100)并且线程2同时调用getA()。线程2是否可以看到80?

public class A {
    private AtomicInteger a; 

    public int getA() {
        return a.get()
    }

    public void setA(int newVal){
        a.set(newVal);
    }   
}

我知道同步它会保证线程2看到100,但AtomicInteger不确定。

2 个答案:

答案 0 :(得分:10)

  

这个类是否是线程安全的?

是的。

  

线程1调用setA(100)并进入该函数但尚未调用a.set(100)并且线程2同时调用getA()。线程2有可能看到80吗?

是。在同步AtomicInteger内的volatile字段的内存屏障代码完成之前,竞争条件可以显示80或100。

线程1甚至可以进入AtomicInteger.set方法并且在内部字段赋值之前,但仍然可以通过get AtomicInteger.get方法返回80.

时,无法保证在其他线程中更新值。保证的是当get()完成时,您获得最新的同步值,当set()完成时,所有其他线程将看到更新。

不能保证不同线程中getter和setter调用的 timing

答案 1 :(得分:1)

正如@Gray指出的那样,这里可能存在竞争条件。

调用get然后调用set不是原子操作。 The Atomic* classes提供无锁原子条件更新操作compareAndSet - 您应该使用该操作来保证线程安全。