AtomicInteger或LongAccumulator

时间:2016-03-12 18:18:40

标签: java multithreading performance java.util.concurrent atomicinteger

有人能说出 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);

    }

}

2 个答案:

答案 0 :(得分:0)

在这个非常精确的例子中(它确实没有用)两个类似乎都是等价的。

使用LongAccumulator,您可以将整个if语句作为lambda表达式传递。 但是:LongAccumulator的java文档声明提供的函数应该是无副作用的,这是不满足的(doSomething写入系统)。

答案 1 :(得分:0)

我想你可能会在这个例子中以与AtomicInteger相同的方式使用LongAccumulator。在这种情况下,答案是

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

LongAccumulator是好的,当你知道许多不同的线程将是更新值,但读数很少甚至更多时,你应该确保读取或重置只发生在一个线程中,如果你关心同步。 但如果你不这样做,LongAccumulator会更好。例如,当你想要计算统计数据时,因为如果你想得到统计数据,你可能更不可能意味着"统计正好在调用"时,你的意思是"当前&#34 ;结果。 这种推理也适用于LongAdder。

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

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

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

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

您可以在文档和课程中了解更多信息。来源

  1. LongAdder
  2. LongAccumulator
  3. About volatile
  4. 效率最高 - 来源:)