AtomicLong运营

Osc*_*Ryz 6 java concurrency atomic atomic-long

我需要执行以下操作:

// average, total, elapsed are Long's

average = ( ( total * average ) + elapsed ) / (++total);
Run Code Online (Sandbox Code Playgroud)

但我想用 AtomicLong

这就是我正在尝试但如果它是正确的我不会得到:

 average.set( (( total.get() * average.get() ) + elapsed) / total.getAndIncrement() );
Run Code Online (Sandbox Code Playgroud)

我怎么知道这是否正确?

Gui*_*one 6

大概您正在使用AtomicLong,因为这些数字是同时访问的。由于涉及到两个数字,并且在同一条语句中同时使用了get和crementAndAndGet,所以我认为AtomicLong不是正确的选择。

我发现AtomicXXX在许多情况下都非常有用。但是在这里,我认为您需要采取艰苦的方式。使数字成为简单的“长”私有变量,创建一个保护对象,然后确保每次访问数字时都在保护对象上进行同步。

我认为这是确保这些操作真正原子的唯一方法。


Gra*_*ray 1

假设这些计算将由多个线程同时调用。我最初并没有将其付诸实践。

如果你想使用AtomicLong来进行预增量计算,那么你应该这样做:

long value = total.getAndIncrement();
average.set((value * average.get()) + elapsed) / (value + 1));
Run Code Online (Sandbox Code Playgroud)

然而,这仍然存在竞争条件,因为平均值可以由其他人在average.get()average.set()调用之间更新,而这不会在更新中生效。

为了完全确定,您需要(正如 @user1657364 在他们的答案中提到的那样)锁定一个守卫对象。