測试AtomicInteger与普通int值在多线程下的递增操作
2017-08-14 14:03
513 查看
日期: 2014年6月10日
作者: 铁锚
Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,当中一部分例如以下:
完整代码:
如果确定是单线程运行,那应该使用 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.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值在多线程下的递增操作
- 测试AtomicInteger与普通int值在多线程下的递增操作
- 测试AtomicInteger与普通int值在多线程下的递增操作
- Java中对AtomicInteger和int值在多线程下递增操作的测试
- AtomicInteger的使用,多线程叠加或叠减
- 多线程(四)~数据操作的原子性,使用原子性操作AutomicInteger替换非原子性的i++的操作
- java int integer java.util.concurrent.atomic.AtomicInteger
- 关于原子操作AtomicInteger、AtomicBoolean等
- 多线程原子操作:AtomicBoolean
- Java的多线程编程模型5--从AtomicInteger开始(自增长实现)
- 使用 AtomicInteger 进行计数(java多线程优化)
- 多线程1:AtomicInteger的使用,多线程叠加或叠减
- 原子操作 AtomicInteger
- 多线程(七):AtomicInteger
- (Kevin笔记三)用AtomicInteger来解决数据表异步操作的问题
- boost中的atomic_int原子操作
- java.util.concurrent(JUC)的研究--》atomic原子操作--》从AtomicInteger开始
- C++11多线程(十):atomic原子操作的高效率(实例)
- Java的多线程编程模型之AtomicInteger
- java i++ 并非原子操作的解决方法——用AtomicInteger