首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >AtomicInteger实现和代码复制

AtomicInteger实现和代码复制
EN

Stack Overflow用户
提问于 2013-03-01 02:07:30
回答 5查看 4.3K关注 0票数 18

警告:问题有点长,但分隔线下面的部分只是出于好奇心。

OracleJDK7的AtomicInteger实现包括以下方法:

public final int addAndGet(int delta) {
    for (;;) {
        int current = get();
        int next = current + delta;         // Only difference
        if (compareAndSet(current, next))
            return next;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;             // Only difference
        if (compareAndSet(current, next))
            return next;
    }
}

很明显,第二个方法可以写成:

public final int incrementAndGet() {
    return addAndGet(1);
}

在该类中还有其他几个类似的代码重复示例。除了性能方面的考虑(*),我想不出任何理由来这么做。我很确定作者在决定这个设计之前做了一些深入的测试。

为什么(或在什么情况下)第一个代码会比第二个代码执行得更好?

(*)我忍不住写了一个快速的微基准测试。它显示(后JIT)支持addAndGet(1)incrementAndGet()的2-4%的系统性能差距(诚然很小,但非常一致)。老实说,我也不能解释这个结果。

输出:

incrementAndGet():905

addAndGet(1):868

incrementAndGet():902

addAndGet(1):863

incrementAndGet():891

addAndGet(1):867

..。

代码:

public static void main(String[] args) throws Exception {
    final int size = 100_000_000;
    long start, end;
    AtomicInteger ai;

    System.out.println("JVM warmup");
    for (int j = 0; j < 10; j++) {
        start = System.nanoTime();
        ai = new AtomicInteger();
        for (int i = 0; i < size / 10; i++) {
            ai.addAndGet(1);
        }
        end = System.nanoTime();
        System.out.println("addAndGet(1): " + ((end - start) / 1_000_000));
        start = System.nanoTime();
        ai = new AtomicInteger();
        for (int i = 0; i < size / 10; i++) {
            ai.incrementAndGet();
        }
        end = System.nanoTime();
        System.out.println("incrementAndGet(): " + ((end - start) / 1_000_000));
    }


    System.out.println("\nStart measuring\n");

    for (int j = 0; j < 10; j++) {
        start = System.nanoTime();
        ai = new AtomicInteger();
        for (int i = 0; i < size; i++) {
            ai.incrementAndGet();
        }
        end = System.nanoTime();
        System.out.println("incrementAndGet(): " + ((end - start) / 1_000_000));
        start = System.nanoTime();
        ai = new AtomicInteger();
        for (int i = 0; i < size; i++) {
            ai.addAndGet(1);
        }
        end = System.nanoTime();
        System.out.println("addAndGet(1): " + ((end - start) / 1_000_000));
    }
}
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15142546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档