Java中对AtomicInteger和int值在多线程下递增操作的测试

网友投稿 257 2023-08-07


Java中对AtomicInteger和int值在多线程下递增操作的测试

java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下:

java.util.concurrent.atomic.AtomicBoolean;

java.util.concurrent.atomic.AtomicInteger;

java.util.concurrent.atomic.AtomicLong;

java.util.concurrent.atomic.AtomicReference;

下面是一个对比  AtomicInteger 与 普通 int 值在多线程下的递增测试,使用的是 junit4;

完整代码:

package test.java;

import java.util.concurrent.CountDownLatch;

import jhttp://ava.util.concurrent.atomic.AtomicInteger;

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

/**

* 测试AtomicInteger与普通int值在多线程下的递增操作

*/

public class TestAtomic {

// 原子Integer递增对象

public static AtomicInteger counter_integer;// = new AtomicInteger(0);

// 一个int类型的变量

public static int count_int = 0;

@Before

public void setUp() {

// 所有测试开始之前执行初始设置工作

counter_integer = new AtomicInteger(0);

}

@Test

public void testAtomic() throws InterruptedException {

// 创建的线程数量

int threadCount = 100;

// 其他附属线程内部循环多少次

int loopCount = 10000600;

// 控制附属线程的辅助对象;(其他await的线程先等着主线程喊开始)

CountDownLatch latch_1 = new CountDownLatch(1);

// 控制主线程的辅助对象;(主线程等着所有附属线程都运行完毕再继续)

CountDownLatch latch_n = new CountDownLatch(threadCount);

// 创建并启动其他附属线程

for (int i = 0; i < threadCount; i++) {

Thread thread = new AtomicIntegerThread(latch_1, latch_n, loopCount);

thread.start();

}

long startNano = System.nanoTime();

// 让其他等待的线程统一开始

latch_1.countDown();

// 等待其他线程执行完

latch_n.await();

//

long endNano = System.nanoTime();

int sum = counter_integer.get();

//

Assert.assertEquals("sum 不等于 threadCount * loopCount,测试失败",

sum, threadCount * loopCount);

System.out.println("--------testAtomic(); 预期两者相等------------");

System.out.println("耗时: " + ((endNano - startNano) / (1000 * 1000)) + "ms");

System.out.println("threadCount = " + (threadCount) + ";");

System.out.println("loopCount = " + (loopCount) + ";");

System.out.println("sum = " + (sum) + ";");

}

@Test

public void testIntAdd() throws InterruptedException {

// 创建的线程数量

int threadCount = 100;

// 其他附属线程内部循环多少次

int loopCount = 10000600;

// 控制附属线程的辅助对象;(其他await的线程先等着主线程喊开始)

CountDownLatch latch_1 = new CountDownLatch(1);

// 控制主线程的辅助对象;(主线程等着所有附属线程都运行完毕再继续)

CountDownLatch latch_n = new CountDownLatch(threadCount);

// 创建并启动其他附属线程

for (int i = 0; i < threadCount; i++) {

Thread thread = new IntegerThread(latch_1, latch_n, loopCount);

thread.start();

}

long startNano = System.nanoTime();

// 让其他等待的线程统一开始

latch_1.countDown();

// 等待其他线程执行完

latch_n.await();

//

long endNano = System.nanoTime();

int sum = count_int;

//

Assert.assertNotEquals(

"sum 等于 threadCount * loopCount,testIntAdd()测试失败",

sum, threadCount * loopCount);

System.out.println("-------testIntAdd(); 预期两者不相等---------");

System.out.println("耗时: " + ((endNano - startNano) / (1000*1000))+ "ms");

Systehttp://m.out.println("threadCount = " + (threadCount) + jmhRUtzSWo";");

System.out.println("loopCounjmhRUtzSWot = " + (loopCount) + ";");

System.out.println("sum = " + (sum) + ";");

}

// 线程

class AtomicIntegerThread extends Thread {

private CountDownLatch latch = null;

private CountDownLatch latchdown = null;

private int loopCount;

public AtomicIntegerThread(CountDownLatch latch,

CountDownLatch latchdown, int loopCount) {

this.latch = latch;

this.latchdown = latchdown;

this.loopCount = loopCount;

}

@Override

public void run() {

// 等待信号同步

try {

this.latch.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

//

for (int i = 0; i < loopCount; i++) {

counter_integer.getAndIncrement();

}

// 通知递减1次

latchdown.countDown();

}

}

// 线程

class IntegerThread extends Thread {

private CountDownLatch latch = null;

private CountDownLatch latchdown = null;

private int loopCount;

public IntegerThread(CountDownLatch latch,

CountDownLatch latchdown, int loopCount) {

this.latch = latch;

this.latchdown = latchdown;

this.loopCount = loopCount;

}

@Override

public void run() {

// 等待信号同步

try {

this.latch.await();

}jmhRUtzSWo catch (InterruptedException e) {

e.printStackTrace();

}

//

for (int i = 0; i < loopCount; i++) {

count_int++;

}

// 通知递减1次

latchdown.countDown();

}

}

}

普通PC机上的执行结果类似如下:

--------------testAtomic(); 预期两者相等-------------------

耗时: 85366ms

threadCount = 100;

loopCount = 10000600;

sum = 1000060000;

--------------testIntAdd(); 预期两者不相等-------------------

耗时: 1406ms

threadCount = 100;

loopCount = 10000600;

sum = 119428988;

从中可以看出, AtomicInteger操作 与 int操作的效率大致相差在50-80倍上下,当然,int很不消耗时间,这个对比只是提供一个参照。

如果确定是单线程执行,那应该使用 int; 而int在多线程下的操作执行的效率还是蛮高的, 10亿次只花了1.5秒钟;

(假设CPU是 2GHZ,双核4线程,理论最大8GHZ,则每秒理论上有80亿个时钟周期,

10亿次Java的int增加消耗了1.5秒,即 120亿次运算, 算下来每次循环消耗CPU周期 12个;

个人觉得效率不错, C 语言也应该需要4个以上的时钟周期(判断,执行内部代码,自增判断,跳转)

前提是: JVM和CPU没有进行激进优化.

)

而 AtomicInteger 效率其实也不低,10亿次消耗了80秒, 那100万次大约也就是千分之一,80毫秒的样子.


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java虚拟机JVM性能优化(三):垃圾收集详解
下一篇:Java中三种简单注解介绍和代码实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~