java AtomicInteger 中的“比较和设置”是如何工作的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32634280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does "Compare And Set" in AtomicInteger works
提问by Onki
AtomicInteger
works with two concepts : CAS and volatile
variable.
AtomicInteger
使用两个概念:CAS 和volatile
变量。
Using volatile
variable insures that the current value will be visible to all threads and it will not be cached.
使用volatile
变量可确保当前值对所有线程可见,并且不会被缓存。
But I am confused over CAS(compare AND set) concept which is explained below:
但我对 CAS(compare AND set) 概念感到困惑,下面解释:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
My question is that whatif(compareAndSet(current, next)
returns false
? Will the value not be updated?
In this case what will happen when a Thread is executing the below case:
我的问题是什么if(compareAndSet(current, next)
返回false
?值不会更新吗?在这种情况下,当线程执行以下情况时会发生什么:
private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
回答by OldCurmudgeon
The atomic objects make use of Compare and Swapmechanism to make them atomic - i.e. it is possible to guarantee that the value wasas specified and is nowat the new value.
原子对象利用比较和交换机制使它们具有原子性——即可以保证值是指定的并且现在是新值。
The code you posted continually tries to set the current value to one more than it was before. Remember that another thread could also have performed a get
and is trying to set it too. If two threads race each other to change the value it is possible for one of the increments to fail.
您发布的代码不断尝试将当前值设置为比以前多 1 的值。请记住,另一个线程也可能执行了 aget
并且也在尝试设置它。如果两个线程相互竞争以更改该值,则其中一个增量可能会失败。
Consider the following scenario:
考虑以下场景:
- Thread 1 calls
get
and gets the value1
. - Thread 1 calculates
next
to be2
. - Thread 2 calls
get
and gets the value1
. - Thread 2 calculates
next
to be2
. - Both threads try to write the value.
- 线程 1 调用
get
并获取值1
。 - 线程 1 计算
next
为2
. - 线程 2 调用
get
并获取值1
。 - 线程 2 计算
next
为2
. - 两个线程都尝试写入该值。
Now because of atomics - only one thread will succeed, the other will recieve false
from the compareAndSet
and go around again.
现在,因为原子能的-只有一个线程会成功,对方将收到false
来自compareAndSet
和再绕过去。
If this mechanism was not used it would be quite possible for both threads to increment the value resulting in only one increment actually being done.
如果不使用这种机制,很可能两个线程都增加该值,导致实际只完成一个增量。
The confusing infinite loop for(;;)
will only really loop if many threads are writing to the variable at the same time. Under very heavy load it may loop around several times but it should complete quite quickly.
for(;;)
只有在许多线程同时写入变量时,令人困惑的无限循环才会真正循环。在非常重的负载下,它可能会循环多次,但应该很快完成。
回答by Dragan Bozanovic
for (;;)
is an infinite loop, so it will just retry the attempt.
for (;;)
是一个无限循环,所以它只会重试。