您的位置:首页 > 其它

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

2017-08-14 14:03 513 查看
日期: 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毫秒的样子.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: