比较几种Counter的自增操作时间
编写一个没有做任何处理的自增
static class StupidCounter implements Counter{
private long counter = 0;
@Override
public void increment() {
counter++;
}
@Override
public long getCounter() {
return counter;
}
}
编写一个加内置锁的自增
static class SyncCounter implements Counter{
private long counter = 0;
@Override
public synchronized void increment() {
counter++;
}
@Override
public long getCounter() {
return counter;
}
}
编写一个使用原子类型的自增
static class AtomicCounter implements Counter{
private AtomicLong counter = new AtomicLong(0);
@Override
public synchronized void increment() {
counter.incrementAndGet();
}
@Override
public long getCounter() {
return counter.get();
}
}
编写一个加显示锁的自增
static class LockCounter implements Counter{
private final Lock lock = new ReentrantLock();
private long counter = 0;
@Override
public void increment() {
try {
lock.lock();
counter++;
}finally {
lock.unlock();
}
}
@Override
public long getCounter() {
return counter;
}
}
编写一个利用Unsafe的CAS操作的自增
static class CASCounter implements Counter{
private Unsafe unsafe ;
private long offset;//偏移量
private volatile long counter = 0;
CASCounter() throws Exception {
unsafe = getUnsafe();//利用反射获取
assert unsafe != null;
offset = unsafe.objectFieldOffset(getClass().getDeclaredField("counter"));//获取偏移量
}
@Override
public void increment() {
long current = counter;
while (!unsafe.compareAndSwapLong(this,offset,current,current+1)){
current = counter;
}
}
@Override
public long getCounter() {
return counter;
}
}
测试
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1000);
Counter counter = new CASCounter();
long start = System.currentTimeMillis();
for (int i = 0;i<1000;i++){
executorService.submit(new CounterRunnable(counter,10000));
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.HOURS);
long end = System.currentTimeMillis();
System.out.println("Counter result : " + counter.getCounter());
System.out.println("Time passed in ms : " + (end-start));
}
结果
/**
* StupidCounter :
* Counter result : 9849270
* Time passed in ms : 696
*
*
* SyncCounter :
* Counter result : 10000000
* Time passed in ms : 966
*
* LockCounter :
* Counter result : 10000000
* Time passed in ms : 452
*
* AtomicCounter :
* Counter result : 10000000
* Time passed in ms : 859
*
* CASCounter :
* Counter result : 10000000
* Time passed in ms : 1144
*/
从结果上看
- 如果不进行任何操作,结果会出问题
显示锁
速度的最快,其次是原子类型
- 可以发现内置锁的速度没有特别差
- 使用Unsafe操作最慢