对于Synchronized、ReentrantLock、Atomic、CAS在并发下面的性能比较测试

对于Synchronized、ReentrantLock、Atomic、CAS在并发下面的性能比较,在JDK1.6和JDK1.8下面测试通过。


我们考虑一个最简单的并发场景,对对象自增字段在并发下面的处理:


接口:Counter


public interface Counter {

void increment();  
long getCounter();

}


执行线程:CounterThread


public class CounterThread implements Runnable{
private Counter counter;
private int num;
public CounterThread(Counter counter , int num){
this.counter = counter;
this.num     = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<num;i++){
counter.increment();
}
}


}


不考虑线程安全的前提下,设计的普通子类:NormalCounter

/**
 * @author chenmeiyang
 * 普通版本
 */
public class NormalCounter implements Counter{

private long num = 0;


@Override
public void increment() {
// TODO Auto-generated method stub
num++;
}


@Override
public long getCounter() {
// TODO Auto-generated method stub
return num;
}


}


主程序入口:ConcurrencyTest


public class ConcurrencyTest {

public static void main(String[] args)throws Exception{

int threads     = 1000;//线程数
int increments  = 100000;
// Counter c = new ReentrantLockCounter();
Counter c = new NormalCounter();
// Counter c = new SynchronizedCounter();
// Counter c = new AtomicCounter();
ExecutorService pool = Executors.newFixedThreadPool( threads );
long start = System.currentTimeMillis();
for(int i=0;i<threads;i++){
pool.submit(new CounterThread(c , increments));
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
System.out.println("=====线程池是否已经停止运行:"+pool.isTerminated());
System.out.println("===========总共耗时:"+(System.currentTimeMillis()-start));
System.out.println("======最终值为:"+c.getCounter());


}


}



执行结果:(线程不安全,数据不正确)

=====线程池是否已经停止运行:true
===========总共耗时:858
======最终值为:94046638


=====线程池是否已经停止运行:true
===========总共耗时:751
======最终值为:96394997


=====线程池是否已经停止运行:true
===========总共耗时:889
======最终值为:95764624


=====线程池是否已经停止运行:true
===========总共耗时:920
======最终值为:97167161


用jdk自带的关键字synchroized加锁处理:SynchronizedCounter

public class SynchronizedCounter implements Counter {

private long num = 0;


@Override
public synchronized void increment() {
// TODO Auto-generated method stub
num++;
}


@Override
public long getCounter() {
// TODO Auto-generated method stub
return num;
}


}


synchronized执行结果:(线程安全,保证了数据的正确性,但是耗时较长)



=====线程池是否已经停止运行:true
===========总共耗时:4625
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:4952
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:4558
======最终值为:100000000



下面,用ReentrantLock锁处理:ReentrantLockCounter

public class ReentrantLockCounter implements Counter{

private long counter = 0;
private ReentrantLock lock = new ReentrantLock();


@Override
public  void increment() {
// TODO Auto-generated method stub
try{
lock.lock();
counter++;
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}

}


@Override
public long getCounter() {
// TODO Auto-generated method stub
return this.counter;
}


}


运行结果:(线程安全,数据正确,而且耗时比synchronized短)

=====线程池是否已经停止运行:true
===========总共耗时:3073
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:3058
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:3044
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:3075
======最终值为:100000000


下面,用Atomic试试:AtomicCounter

public class AtomicCounter implements Counter{

private AtomicLong num = new AtomicLong(0);


@Override
public void increment() {
// TODO Auto-generated method stub
num.incrementAndGet();
}


@Override
public long getCounter() {
// TODO Auto-generated method stub
return num.get();
}


}


运行结果,(线程安全,数据正确,耗时比ReentrantLock还短)

=====线程池是否已经停止运行:true
===========总共耗时:2636
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:2449
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:2558
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:2543
======最终值为:100000000


最后,我们再试下CAS:

public class CASCounter implements Counter{

private volatile long num = 0;
private Unsafe unsafe;
private long offset;

public CASCounter() throws Exception {
unsafe = this.getUnsafe();
offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("num"));
    }

private Unsafe getUnsafe()throws Exception{
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
return unsafe;
}




@Override
public void increment() {
// TODO Auto-generated method stub
long before = num;
while (!unsafe.compareAndSwapLong(this, offset, before, before + 1)) {
     before = num;
}
}


@Override
public long getCounter() {
// TODO Auto-generated method stub
return num;
}


}


运行结果:(线程安全,数据正确,但是耗时很长)

=====线程池是否已经停止运行:true
===========总共耗时:8505
======最终值为:100000000


=====线程池是否已经停止运行:true
===========总共耗时:9003
======最终值为:100000000




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值