AtomicInteger与同步的getter/setter方法

5

这个类是线程安全的吗?

有可能看到不一致的值吗?比如说,初始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是否也是如此。

2个回答

10

这个类是线程安全的吗?

是的,它是线程安全的。

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

是的,直到在AtomicInteger内部同步易失性字段的内存屏障代码完成之前,竞争条件可能会显示80或100。

甚至可以在Thread 1进入AtomicInteger.set方法并且还没有执行内部字段赋值之前,仍然可能通过getAtomicInteger.get方法返回80。

关于其他线程何时更新值,没有任何保证。确保的是当get()完成时,你将获得最新的同步值,并且当set()完成时,所有其他线程将看到更新。

对于不同线程中getter和setter调用的时间,没有任何保证。


1

正如@Gray所指出的,这里存在竞态条件的可能性。

调用get然后再调用set不是一个原子操作。Atomic*提供了无锁的原子条件更新操作compareAndSet - 你应该使用它来保证线程安全。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接