LongAdder与AtomicInteger并发性能的简单比较测试

测试代码如下:

package lhever.JVM;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class AtomicTest
{

    public  static final  int MAX_THREAD_COUNT = 10;
    private static final int TASK_COUNT = 10;
    private static final int TARGET_COUNT = 100000000;

    private AtomicLong atomicLongVal = new AtomicLong(0);
    private LongAdder longAdderVal = new LongAdder();

    private static CountDownLatch latchForAtomicLong = new CountDownLatch(TASK_COUNT);
    private static CountDownLatch latchForLongAdder = new CountDownLatch(TASK_COUNT);

    public class AtomicLongThread implements Runnable {
        protected String name;
        protected long startTime;

        public AtomicLongThread(long startTime) {
         this.startTime = startTime;
        }

        @Override
        public void run()
        {
            long v = atomicLongVal.get();
            while(v < TARGET_COUNT) {
                v = atomicLongVal.incrementAndGet();
            }
            long endTime = System.currentTimeMillis();
            System.out.println("AtomicLongThread Spend:" + (endTime - startTime) + "ms, v = " + v);
            latchForAtomicLong.countDown();
        }

    }

    public class LongAddderThread implements Runnable {
        protected String name;
        protected long startTime;

        public LongAddderThread(long startTime) {
         this.startTime = startTime;
        }

        @Override
        public void run()
        {
            long v = longAdderVal.sum();
            while(v < TARGET_COUNT) {
                longAdderVal.increment();
                v = longAdderVal.sum();
            }
            long endTime = System.currentTimeMillis();
            System.out.println("LongAddderThread Spend:" + (endTime - startTime) + "ms, v = " + v);
            latchForLongAdder.countDown();
        }

    }

    public void testAtomicLongThread() throws InterruptedException {
        ExecutorService exe = Executors.newFixedThreadPool(MAX_THREAD_COUNT);
        long startTime = System.currentTimeMillis();
        AtomicLongThread atomicIntegerThread = new AtomicLongThread(startTime);
        for(int i = 0; i < TASK_COUNT; i++) {
            exe.submit(atomicIntegerThread);
        }
        latchForAtomicLong.await();
        exe.shutdown();
    }

    public void testLongAdderThread() throws InterruptedException {
        ExecutorService exe = Executors.newFixedThreadPool(MAX_THREAD_COUNT);
        long startTime = System.currentTimeMillis();
        LongAddderThread longAddderThread = new LongAddderThread(startTime);
        for(int i = 0; i < TASK_COUNT; i++) {
            exe.submit(longAddderThread);
        }
        latchForLongAdder.await();
        exe.shutdown();
    }

    /**
     * 下面的测试表明,AtomicLong的并发性能比LongAdder要差,在线程竞争越剧烈的场合,其表现出来的性能会更加优越
     * @param args
     * @throws InterruptedException
     * @author lhever 2017年4月4日 下午11:10:06
     * @since v1.0
     */
    public static void main(String[] args) throws InterruptedException {

       /**
        * MAX_THREAD_COUNT、TASK_COUNT的值都为3时候测试结果如下:
        */
        AtomicTest test = new AtomicTest();
        test.testAtomicLongThread();
        test.testLongAdderThread();

        /*
        在本人的win7 64位系统 运行结果如下
        AtomicLongThread Spend:2258ms, v = 100000001
        AtomicLongThread Spend:2258ms, v = 100000002
        AtomicLongThread Spend:2258ms, v = 100000000
        LongAddderThread Spend:2155ms, v = 100000000
        LongAddderThread Spend:2155ms, v = 100000000
        LongAddderThread Spend:2155ms, v = 100000000
        */

        /**
         * MAX_THREAD_COUNT、TASK_COUNT的值都为10时候测试结果如下:
         */
        AtomicTest test1 = new AtomicTest();
        test1.testAtomicLongThread();
        test1.testLongAdderThread();
       /*
                     在本人的win7 64位系统 运行结果如下
        AtomicLongThread Spend:2889ms, v = 100000005
        AtomicLongThread Spend:2890ms, v = 100000002
        AtomicLongThread Spend:2890ms, v = 100000006
        AtomicLongThread Spend:2889ms, v = 100000003
        AtomicLongThread Spend:2889ms, v = 100000004
        AtomicLongThread Spend:2890ms, v = 100000007
        AtomicLongThread Spend:2889ms, v = 100000000
        AtomicLongThread Spend:2889ms, v = 100000001
        AtomicLongThread Spend:2891ms, v = 100000008
        AtomicLongThread Spend:2892ms, v = 100000009
        LongAddderThread Spend:2054ms, v = 100000005
        LongAddderThread Spend:2054ms, v = 100000003
        LongAddderThread Spend:2054ms, v = 100000003
        LongAddderThread Spend:2054ms, v = 100000007
        LongAddderThread Spend:2054ms, v = 100000002
        LongAddderThread Spend:2054ms, v = 100000006
        LongAddderThread Spend:2054ms, v = 100000007
        LongAddderThread Spend:2054ms, v = 100000004
        LongAddderThread Spend:2054ms, v = 100000003
        LongAddderThread Spend:2057ms, v = 100000008
        */


    }



}
<think>首先,用户的问题是:“我想了解或使用AtomicInteger的初始化方法 请问Java AtomicInteger 初始化值 0 的使用方法”。这集中在AtomicInteger的初始化方法上,特别是如何初始化为0。 从系统级指令: - 所有行内数学表达式必须用$...$格式。 - 独立公式用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:有个引用关于AtomicInteger。 站内引用: - 引用[1]:提到使用带有初始值的构造函数初始化,如`AtomicInteger atomicInteger = new AtomicInteger(10);` - 引用[2]:详细说明基本用法,包括初始化:`AtomicInteger atomicInteger = new AtomicInteger();` 和 `AtomicInteger initializedAtomicInteger = new AtomicInteger(10);` - 引用[3]:提到AtomicInteger用于线程并发场景。 - 引用[4]:讨论CAS和性能。 - 引用[5]:说明不能用作Integer的替代,但扩展Number。 用户需求是初始化值为0。在Java中,AtomicInteger的默认构造函数初始化为0,或者可以显式指定0。 回答结构: 1. **介绍AtomicInteger**:简要解释是什么和为什么使用。 2. **初始化方法**: - 默认构造函数:初始化为0。 - 带参数的构造函数:指定初始值,如0。 3. **示例代码**:提供代码示例。 4. **解释**:解释如何工作。 5. **注意事项**:基于引用,提醒线程场景。 6. **相关问题**:生成相关问题。 生成相关问题: - 基于用户问题,如其他初始化方式、方法使用、性能等。 确保中文回答。 最终输出格式: - 回答部分。 - §§相关问题§§部分。</think>### Java AtomicInteger 初始化值为 0 的使用方法 AtomicInteger 是 Java 并发包 `java.util.concurrent.atomic` 中的一个类,用于在线程环境下安全地操作整数值。它通过原子操作(如 CAS)确保线程安全,避免数据竞争问题。初始化值为 0 是常见场景,例如在计数器或并发统计中。下面我将逐步解释初始化方法,并提供示例代码和注意事项。 #### 1. **初始化方法** AtomicInteger 提供了两种构造函数来初始化值: - **默认构造函数**:直接创建对象,初始值自动设为 0。 - 语法:`AtomicInteger atomicInt = new AtomicInteger();` - **带参数的构造函数**:显式指定初始值,如设为 0。 - 语法:`AtomicInteger atomicInt = new AtomicInteger(0);` - 这两种方法在功能上等效,初始值都为 0。默认构造函数更简洁,而带参数构造函数可增强代码可读性,尤其在需要明确初始值时[^2][^5]。 #### 2. **示例代码** 以下是一个完整的 Java 示例,展示如何初始化为 0 并进行基本操作: ```java import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerExample { public static void main(String[] args) { // 方法 1: 使用默认构造函数初始化值为 0 AtomicInteger counter1 = new AtomicInteger(); System.out.println("初始值 (默认): " + counter1.get()); // 输出: 0 // 方法 2: 显式初始化值为 0 AtomicInteger counter2 = new AtomicInteger(0); System.out.println("初始值 (显式): " + counter2.get()); // 输出: 0 // 测试原子操作: 递增并获取新值 int newValue = counter1.incrementAndGet(); // 值从 0 变为 1 System.out.println("递增后值: " + newValue); // 输出: 1 } } ``` - **解释**: - `new AtomicInteger()`:默认构造函数内部设置初始值为 0,无需额外参数[^1][^2]。 - `new AtomicInteger(0)`:显式指定初始值为 0,这在代码中更易理解。 - 后续使用 `incrementAndGet()` 方法进行原子递增,确保线程安全。 #### 3. **注意事项** - **线程安全**:AtomicInteger 适用于线程场景,如计数器或状态标志。它通过 CAS(Compare-And-Swap)机制实现原子操作,避免锁竞争[^3][^4]。 - **性能考虑**:在高并发下,CAS 可能导致 CPU 自旋(消耗资源)。如果竞争激烈,建议使用 `LongAdder` 等优化类[^4]。 - **不能替代 Integer**:AtomicInteger并发工具,不是 `java.lang.Integer` 的替代品。它扩展了 `Number` 类,但仅用于原子操作场景[^5]。 - **初始值选择**:初始化为 0 是安全的,但如果需要其他值(如 10),使用带参数构造函数[^1][^2]。 通过以上方法,您可以轻松初始化和使用 AtomicInteger 值为 0。在线程应用中,这能有效提升性能和可靠性[^3][^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值