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 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毫秒的样子.



相关阅读:
解决Win7系统USB接口没反应的方法
在Android中 获取正在运行的Service 实例
使用JQuery库提供的扩展功能实现自定义方法
JS实现两个大数(整数)相乘
js post提交调用方法
解决js下referer兼容各大浏览器的方法
js实现点击按钮后给Div图层设置随机背景颜色的方法
浅析MYSQL REPEATABLE-READ隔离级别
扩展KMP算法(Extend KMP)
防止Xen VPS用户自己修改IP地址的方法
html无序列表标签和有序列表标签使用示例
2015款Macbook安装Win10多分区教程图文详解
Oracle中检查外键是否有索引的SQL脚本分享
兼容IE6、IE7的min-width、max-width写法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 蒋方舟:恋,还是不恋? 烦恼何时才在现实中停息作文100字 点评学生作文西瓜虫1000字 设备三级保养管理制度 分享是美丽的作文700字 爱你不只是因为你的美而已 爱到了尽头,我却以为我还在幸福着被你爱着 这里有属于我的世界作文500字 形容稀奇古怪的词语 感受WTO_关于感受WTO的初中作文700字 生的意义 生活励志语录 描写街巷道路的好词 平安夜给老板的祝福语 我记忆中的笑容 2012年感恩母亲节作文:母亲的泪 就那么远去了 我的世界杯情结 小朋友摔倒了 表现体广告中的论说体广告_广告启事 2015集体合同 班里的“不速之客”500字 在我们这个年龄作文500字 心情日志 人们渐渐在掌声和鲜花中迷失了自 烧烤小记 小学教师“三严三实”专题教育自我批评发言稿 心事微凉(诗歌) 我的校园作文1600字 2010年区国税局工作要点 给父母的感恩信 红颜有梦 15:赏画 毕业演讲 区农村信用联社员工聘用实施办法 新老师 三年级音乐教师上期工作总结 广播稿怎么写 小学三年级作文450字:机智的老山羊 一生都感激的人 结婚前与情侣完成的几件事 相信自己,励志歌曲歌词 2016励志晚安说说 大学生的仪容仪表要求 团结友爱每一天观《葫芦兄弟》有感350字 雨,一直在下 我妈妈的童年真苦200字 你的就是你的,我的就是我的!作文600字 岁月飘飞,栀子花开 一个人的爱 小学四年级作文350字:喜羊羊与灰太狼之七色花2

Copyright © 2016 phpStudy |