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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:32:22  来源:igfitidea点击:

How does "Compare And Set" in AtomicInteger works

javamultithreadingconcurrencyvolatile

提问by Onki

AtomicIntegerworks with two concepts : CAS and volatilevariable.

AtomicInteger使用两个概念:CAS 和volatile变量。

Using volatilevariable 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 getand 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:

考虑以下场景:

  1. Thread 1 calls getand gets the value 1.
  2. Thread 1 calculates nextto be 2.
  3. Thread 2 calls getand gets the value 1.
  4. Thread 2 calculates nextto be 2.
  5. Both threads try to write the value.
  1. 线程 1 调用get并获取值1
  2. 线程 1 计算next2.
  3. 线程 2 调用get并获取值1
  4. 线程 2 计算next2.
  5. 两个线程都尝试写入该值。

Now because of atomics - only one thread will succeed, the other will recieve falsefrom the compareAndSetand 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 (;;)是一个无限循环,所以它只会重试。