问题描述
我正在浏览的源代码,以了解该类提供的原子操作是如何实现原子性的。例如 AtomicInteger.getAndIncrement()方法源如下
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
我无法理解无限循环中的操作序列。它是否用于Java内存模型(JMM)中的任何特殊目的。请帮我找到一个描述性的理解。提前致谢。
I am not able to understand the purpose of writing the sequence of operations inside a infinite for loop. Does it serve any special purpose in Java Memory Model (JMM). Please help me find a descriptive understanding. Thanks in advance.
推荐答案
为了理解为什么它是一个无限循环,我发现有助于理解 compareAndSet
会返回false。
To understand why it is in an infinite loop I find it helpful to understand what the compareAndSet
does and how it may return false.
Atomically sets the value to the given updated value if the current
value == the expected value.
Parameters:
expect - the expected value
update - the new value
Returns:
true if successful. False return indicates that the actual value was not
equal to the expected value
所以你读取返回
消息,并问这是怎么可能的?
So you read the Returns
message and ask how is that possible?
在接近同一时间调用 incrementAndGet
,他们都进入并看到值 current == 1
。这两个线程将创建一个线程局部 next == 2
,并尝试通过 compareAndSet
设置。只有一个线程将赢得根据文档,失去的线程必须重试。
If two threads are invoking incrementAndGet
at close to the same time, and they both enter and see the value current == 1
. Both threads will create a thread-local next == 2
and try to set via compareAndSet
. Only one thread will win as per documented and the thread that loses must try again.
这是CAS的工作原理。
This is how CAS works. You attempt to change the value if you fail, try again, if you succeed then continue on.
现在简单地将字段声明为volatile将不起作用,因为增量是非原子。所以这样的东西是不安全从我解释的情况
Now simply declaring the field as volatile will not work because incrementing is not atomic. So something like this is not safe from the scenario I explained
volatile int count = 0;
public int incrementAndGet(){
return ++count; //may return the same number more than once.
}
这篇关于如何在java.util.concurrent.atomic包中定义的类中实现原子性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!