Java中对AtomicInteger和int值在多线程下递增操作的测试
作者:junjie 时间:2023-10-22 18:32:03
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 java.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");
System.out.println("threadCount = " + (threadCount) + ";");
System.out.println("loopCount = " + (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();
} 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毫秒的样子.
标签:Java,AtomicInteger,int,多线程,递增操作,测试
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Intellij IDEA 的maven项目通过Java代码实现Jetty的Http服务器(推荐)
2022-02-19 20:29:13
![](https://img.aspxhome.com/file/2023/2/119172_0s.png)
c#获取存储过程返回值示例分享
2021-08-24 18:45:48
Java如何基于ProcessBuilder类调用外部程序
2023-11-27 20:19:57
![](https://img.aspxhome.com/file/2023/0/59210_0s.png)
Android 8.0实现蓝牙遥控器自动配对
2021-08-05 08:24:16
Java实现打印二叉树所有路径的方法
2021-07-13 15:52:57
![](https://img.aspxhome.com/file/2023/8/84178_0s.png)
C#实现微信红包功能
2023-11-30 02:49:51
![](https://img.aspxhome.com/file/2023/7/86977_0s.jpg)
WPF使用DrawingContext实现绘制刻度条
2023-06-19 08:35:17
![](https://img.aspxhome.com/file/2023/9/116519_0s.gif)
java中List接口与实现类介绍
2022-11-17 02:54:40
spring mvc4中相关注解的详细讲解教程
2021-10-11 23:21:17
C#实现简单记事本程序
2022-07-20 23:52:37
![](https://img.aspxhome.com/file/2023/7/83237_0s.jpg)
Android中Activity之间跳转和参数传递的实例
2023-01-31 21:40:32
![](https://img.aspxhome.com/file/2023/3/98653_0s.jpg)
Android中自定义ImageView添加文字说明详解
2022-10-23 18:39:27
![](https://img.aspxhome.com/file/2023/4/126664_0s.png)
学习Java HashMap,看这篇就够了
2023-11-11 11:18:56
![](https://img.aspxhome.com/file/2023/2/59422_0s.png)
Android实现倒计时效果
2021-10-13 03:25:29
![](https://img.aspxhome.com/file/2023/3/138643_0s.jpg)
C#使用windows服务开启应用程序的方法
2022-08-14 04:37:14
详解maven中profiles使用实现
2022-11-13 23:14:24
![](https://img.aspxhome.com/file/2023/2/64512_0s.jpg)
Flutter 实现下拉刷新上拉加载的示例代码
2023-08-18 21:31:16
![](https://img.aspxhome.com/file/2023/8/88668_0s.gif)
Android开发Compose框架使用开篇
2023-06-08 19:14:19
![](https://img.aspxhome.com/file/2023/8/94988_0s.jpg)
深入理解Android手势识别
2021-08-12 11:05:16
Java 多线程并发AbstractQueuedSynchronizer详情
2022-12-22 10:54:35