0

在下面的示例中,有人可以判断LongAccumulator是否可以成为AtomicInteger的更好选择吗?

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class IncrementThread implements Runnable{

    AtomicInteger atomicint = new AtomicInteger();

    public IncrementThread(AtomicInteger atominint) {
        this.atomicint = atominint;

    }

    @Override
    public void run() {
        while(true)
            if(atomicint.incrementAndGet()==4){doSomething(); atomicint.set(0);}
    }

    private void doSomething() {
        System.out.println(Thread.currentThread().getName() + " : counter reached to 4");
    }

    public static void main(String[] args) {

        AtomicInteger atomicint = new AtomicInteger();
        IncrementThread incThread1 = new IncrementThread(atomicint);
        IncrementThread incThread2 = new IncrementThread(atomicint);
        IncrementThread incThread3 = new IncrementThread(atomicint);

        ExecutorService threadPool = Executors.newCachedThreadPool();

        threadPool.execute(incThread1);
        threadPool.execute(incThread2);
        threadPool.execute(incThread3);

    }

}
4

2 回答 2

0

我想您可能会以与本示例中的 AtomicInteger 相同的方式使用 LongAccumulator。在这种情况下,答案是否定的。

当您调用 get() 之类的方法时,LongAccumulator 只会累积值并计算结果。您还可以清除类似的 LongAccumulator.reset() 方法,当它有 4 个值时。但是 LongAccumulator 中的所有这些方法都不是线程安全的,并且您可能会得到不可预知的结果,因为您使用多个线程进行读取和更新。

LongAccumulator 很好,当您知道许多不同的线程将更新值,但读取很少且更多时,如果您关心同步,您应该确保读取或重置仅发生在一个线程中。但如果你不这样做,LongAccumulator 可能会更好。例如,当您想统计统计信息时,因为如果您想获得统计信息,您更可能不是指“恰好在调用时间的统计信息”,而是指“当前”结果之类的东西。这个推理也适用于 LongAdder。

在您的示例中,有两个可能的改进。首先,您可以使用:

while(true)
        if(atomicint.incrementAndGet()==4){doSomething(); atomicint.compareAndSet(4, 0);}

现在您检查一下,您是否重置了 atomicint 变量的相同状态。

另一个可能的改进 - 不要使用 AtomicLong 或 LongAccumulator,只需使用带有 volatile 关键字的简单 long 变量。它在这里会更简单,更适用,因为在这个例子中你不使用功能(就像我在第一个改进中提到的那样)。

您可以在文档和类的来源中了解更多信息

  1. 长加法器
  2. 长累加器
  3. 关于易失性
  4. 最有效的来源:)
于 2016-12-20T11:33:37.527 回答
0

在这个非常精确的示例中(实际上并没有什么用处),这两个类似乎是等价的。

使用 LongAccumulator,您可以将整个 if 语句作为 lambda 表达式传递。但是: LongAccumulator 的 Java 文档指出,提供的函数应该是没有副作用的,但没有实现(doSomething 写入系统输出)。

于 2016-03-12T18:41:09.447 回答