博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
测试AtomicInteger与普通int值在多线程下的递增操作
阅读量:7215 次
发布时间:2019-06-29

本文共 4735 字,大约阅读时间需要 15 分钟。

日期: 2014年6月10日

作者:

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(); 预期两者相等-------------------耗时: 85366msthreadCount = 100;loopCount = 10000600;sum = 1000060000;--------------testIntAdd(); 预期两者不相等-------------------耗时: 1406msthreadCount = 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毫秒的样子.

转载于:https://www.cnblogs.com/lanzhi/p/6467010.html

你可能感兴趣的文章
关于修改linux hostname的问题,尤其是redhat 7修改hostname的方式
查看>>
nginx服务器的负载均衡和动静分离(未完)
查看>>
php 处理ftp常用操作与方法
查看>>
nutz 结合QueryResult,Record 自定义分页查询,不构建pojo 整合
查看>>
Mac下安装Pyqt
查看>>
m-orchastration system
查看>>
Golang 微框架 Gin 简介
查看>>
redis 中 set 和 hset 有什么不同,什么时候使用 hset 什么时候使用set?
查看>>
axios介绍与使用说明 axios中文文档
查看>>
Java基础-Date类常用方法介绍
查看>>
Pythonic版冒泡排序和快速排序(附:直接插入排序)
查看>>
各大厂分布式链路跟踪系统架构对比
查看>>
WSL与Windows交互实践
查看>>
《二叉树》学习心得
查看>>
【基础】CSS实现多重边框的5种方式
查看>>
Eclipse下把jar包放到工程lib下和通过buildpath加载有什么不同(解决找不到类的中级方法)...
查看>>
gradle新建工程,多项目依赖,聚合工程
查看>>
变量命名神器Codelf
查看>>
iBase4J部署总结
查看>>
IASetIndexBuffer Offset
查看>>