Dav*_*rad 10
不,它不是原子的,但是如果另一个线程修改了 AtomicReference,那么 pareAndSet 调用将失败,它将再次循环,获取值,增加它,然后尝试再次设置它。迟早(可能)它会成功并将 AtomicReference 持有的 BigInteger 更新为下一个数字。
小智 9
您类中的方法incrementAndGet
将不是原子的。这就是为什么。
这些Atomic*
类使用volatile
值引用。这些值的内存偏移量也保存在实例中,它们可以使用这些实例在循环中获取-增量-比较-设置,直到当前线程能够一次性完成所有操作(即,没有另一个线程执行增量之间)。
Atomic*
正如我所看到的,由于内在的“受信任”类对实现的访问,这对于这些是可能的Unsafe
。这些Unsafe
实现具有使用函数以原子方式进行比较和设置的方法。native
在您提到的情况下,我们将不得不求助于使用synchronized
块,其等效Lock
的基于实现或简单地使用AtomicReference
. 像这样:
public class AtomicBigInteger{
private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>();
public AtomicBigInteger(BigInteger bigInteger) {
valueHolder.set(bigInteger);
}
public BigInteger incrementAndGet() {
return valueHolder.updateAndGet( bigInt -> bigInt.add( BigInteger.ONE ) );
}
}
但是,由于我们正在处理BigInteger
,因此也必须审查此实现,因为AtomicReference.updateAndGet(..)
可能必须执行的迭代次数可能很大,因为BigInteger.add( BigInteger )
涉及很多步骤,这与添加两个int
s 不同。
更多推荐
都是,原子,操作
发布评论