2012-03-21 74 views
5

这个类是线程安全的吗?AtomicInteger vs synchronized getters/setters

是否有可能看到不一致的值?可以说最初a的值是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。

回答

9

这个类是线程安全的吗?

是的。

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

是的。直到与AtomicInteger内部的易失性字段同步的内存屏蔽代码完成,竞争条件可以显示80或100.

线程1甚至可以输入AtomicInteger.set方法,并位于内部字段赋值之前,仍然可以返回80通过获得AtomicInteger.get方法。

关于的值不会被其他线程更新。什么是保证是当get()完成,你得到最新的同步值,当完成时,所有其他线程将看到更新。

无法保证时间 getter和setter调用在不同的线程。

1

正如@格雷指出的那样,这里有可能出现竞赛状况。

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