日期: 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(); 预期两者相等-------------------
耗时: 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毫秒的样子.

測试AtomicInteger与普通int值在多线程下的递增操作的更多相关文章

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

    日期: 2014年6月10日 作者: 铁锚 Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下: java.util.concurrent.atomic.AtomicB ...

  2. 鹅厂揭秘——高端大气的App电量測试

    怎样评价我们开发出来的应用是耗电还是不耗电,怎样測试?这就是我们今天讨论的主题--电量測试,一个在移动应用中新出现的測试类型. 作者简单介绍 watermark/2/text/aHR0cDovL2Js ...

  3. android 性能測试iozone篇

    一:简单介绍 iozone是一个文件系统的benchmark工具, 用于測试不同的操作系统中文件系统的读写性能, 能够測试下面13种模式 0=write/rewrite 1=read/re-read ...

  4. 系统吞吐量、TPS(QPS)、用户并发量、性能測试概念和公式

    PS:以下是性能測试的主要概念和计算公式,记录下: 一.系统吞度量要素: 一个系统的吞度量(承压能力)与request对CPU的消耗.外部接口.IO等等紧密关联.单个reqeust 对CPU消耗越高, ...

  5. iOS自己主动化測试的那些干货

    前言 假设有測试大佬发现内容不正确.欢迎指正,我会及时改动. 大多数的iOS App(没有持续集成)迭代流程是这种 也就是说.測试是公布之前的最后一道关卡.假设bug不能在測试中发现,那么bug 就会 ...

  6. OpenGL学习脚印:深度測试(depth testing)

    写在前面 上一节我们使用AssImp载入了3d模型,效果已经令人激动了.可是绘制效率和场景真实感还存在不足,接下来我们还是要保持耐心,继续学习一些高级主题,等学完后面的高级主题,我们再次来改进我们载入 ...

  7. 学习使用Jmeter做压力測试(一)--压力測试基本概念

    一.性能測试的概念         性能測试是通过自己主动化的測试工具模拟多种正常峰值及异常负载条件来对系统的各项性能指标进行測试.负载測试和压力測试都属于性能測试,两者能够结合进行. 通过负载測试, ...

  8. LINPACK測试

    1简单介绍 LINPACK是线性系统软件包(Linear system package) 的缩写. Linpack如今在国际上已经成为最流行的用于測试高性能计算机系统浮点性能的benchmark.通过 ...

  9. Selenium2 Python 自己主动化測试实战学习笔记(五)

    7.1 自己主动化測试用例 无论是功能測试.性能測试和自己主动化測试时都须要编写測试用例,測试用例的好坏能准确的体现了測试人员的经验.能力以及对项目的深度理解. 7.1.1 手工測试用例与自己主动化測 ...

随机推荐

  1. VisualStudio:如何监控 ADO.NET?

    背景 很多场景下我们都需要监控 ADO.NET,如:查看某些框架(ORM)生成的 SQL.如何在不能使用 SQL Profile 的情况下监控 SQL 呢?VS 为我们提供了一个工具,本文做一些介绍! ...

  2. git服务器的建立——Git折腾小记

    转自:http://blog.csdn.net/xsl1990/article/details/25486211 如果你能看到一些sshd相关的进程信息,则说明你已经有这个服务了,否则(或者你想更新的 ...

  3. 超能英雄第一至四季/全集Heroes迅雷下载

    本季第一.二.三.四季 Heroes Season (2006-2009) 看点:<Heroes>是NBC电视台于2006年九月开播的最新科幻电视剧.Heroes(中文剧名为“英雄”或“天 ...

  4. JAVA中对List<map<String,Object>>根据map某个key值进行排序

    方法compareTo()比较此对象与指定对象的顺序.如果该对象小于.等于或大于指定对象,则分别返回负整数.零或正整数.返回整数,1,-1,0:返回1表示大于,返回-1表示小于,返回0表示相等. 普通 ...

  5. [Web 前端 ] 五大WEB主流浏览器及四大内核

    现在国内常见的浏览器有:IE.Firefox.Safari.Opera.Google Chome.QQ浏览器.搜狗浏览器.百度浏览器.猎豹浏览器.UC浏览器.360浏览器.遨游浏览器.世界之窗浏览器等 ...

  6. Greenplum入门——基础知识、安装、常用函数

    Greenplum入门——基础知识.安装.常用函数 2017年10月08日 22:03:09 在咖啡里溺水的鱼 阅读数:8709    版权声明:本文为博主原创,允许非商业性质转载但请注明原作者和出处 ...

  7. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  8. Statistical Artifact (error)

    In natural science and signal processing, an artifact is any error in the perception or representati ...

  9. [置顶] 不刷机让越狱后的iphone恢复出厂设置

    iphone越狱后,设置里的清除所有内容和设置选项是不生效的,选上之后菊花转个不停,只能强制退出,还有白苹果的危险. 若想恢复出厂设置有两个办法: 一.刷机 最直接的办法,我觉得itunes配合ito ...

  10. maven项目里,junit的test程序不能访问src/test/resource下面的配置

    问题描述 最近在写单元测试,但是不想改动源代码,所以想自己在本test目录下建一个resouces文件夹并添加对应的配置文件,可是发现test程序无法读取这个resouces文件夹下的配置. 问题解决 ...