当前位置:  编程技术>java/j2ee

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

    来源: 互联网  发布时间:2014-11-08

    本文导语:  Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下: java.util.concurrent.atomic.AtomicBoolean; java.util.concurrent.atomic.AtomicInteger; java.util.concurrent.atomic.AtomicLong; java.util.concurrent.atomic.AtomicReference; 下...

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硬币翻转倍数递增试算实例
  • Java中多线程相关类Thread介绍
  • java 线程,对当前线程(非主线程)调用sleep,为什么主线程(窗口)也没反应了
  • 输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程
  • java基本教程之多线程基本概念 java多线程教程
  • 请问在java多线程中,是只有run(){}内的代码运行在一个新线程下呢?还是这个类中的代码都运行在一个新线程下?
  • 用什么方法可以查看在windows下jvm下运行当前java程序的线程数和线程名称?
  • java多线程编程之捕获子线程异常示例
  • java线程怎么调用java的application.class?
  • java多线程编程之使用runnable接口创建线程
  • java线程中如何降低CPU的占用率?我这几个线程会不会死锁?
  • java线程之使用Runnable接口创建线程的方法
  • java 多线程问题
  • Java线程的相关方法详细解析
  • 紧急求助java多线程编程!!!!!!!!!!!!!
  • java线程,回答得比较深就好了
  • Java多线程之中断线程(Interrupt)的使用详解
  • 关于java线程调度优先级
  • java基本教程之线程让步 java多线程教程
  • Java多线程单元测试 Thread Weaver
  • 求教JAVA中的延时函数!不是用于线程中的!
  • java中多线程的问题
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: atomicinteger定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: getandincrement定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: decrementandget定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: getanddecrement定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: incrementandget定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: set定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: lazyset定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: getandset定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: getandadd定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: addandget定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: tostring定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: doublevalue定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: floatvalue定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: longvalue定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: intvalue定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: compareandset定义及介绍
  • java命名空间java.util.concurrent.atomic类atomicinteger的类成员方法: weakcompareandset定义及介绍
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • mysql iis7站长之家
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 本人想学java,请问java程序员的待遇如何,和java主要有几个比较强的方向
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: stringflavor定义及介绍
  • 我对JAVA一窍不通,可惜别人却给我一个Java的project,要我做一个安装程序,请问哪里有JAVA INSTALLER下载,而且我要不要安装java的sdk才能完成此项任务?
  • java命名空间java.security类keystore的类成员方法: getdefaulttype定义及介绍
  • 新年第一天,让我们讨论一下未来一年JAVA的发展趋势! 个人认为,JAVA将主要朝ERP和JAVA手机方面发展!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3