来自:https://www.cnblogs.com/willowWind/p/8551926.html
今天使用synchronized和java unsafe cas接口对比了下同一个操作下的的相关性能,
为后面多线程情况下使用synchronized同步阻塞方式或者是unsafe cas非阻塞做了一个参考。
测试用例:
启用多个线程进行计数相加到一亿,首先是synchronized方式;
计算类如下:
package com.wc.thread;
public class SyncCounter implements CountBase{
private volatile long value = 0;
@Override
public synchronized long getValue() {
// TODO Auto-generated method stub
return value;
}
@Override
public synchronized long increment() {
// TODO Auto-generated method stub
if (value <= 100000000)
return ++value;
else
return value;
}
}
测试类:
package com.wc.thread;
public class Test {
public static void main(String[] args) {
CountBase counter= new SyncCounter();
for(int i =0; i< 64; i++)
{
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
long begin = System.currentTimeMillis();
while(true)
{
if(counter.getValue() >= 100000000)
break;
else
{
counter.increment();
}
}
long end = System.currentTimeMillis();
long time = end - begin;
System.out.println("The process is " + Thread.currentThread().getName() +
" Value is :" + counter.getValue() + ";" + "time is:" + time);
}
}
);
thread.start();
}
}
}
测试相关数据如下:
当线程数为8时,性能明显提升,但是8到32个线程来说,每个线程的平均时间基本差不多,基本没有提升,到了64个线程的时候,性能又有一点提升。
如果换成CAS实现多线程累加数为一亿,时间又会怎么样呢,我们先来看下测试代码:
计算类如下:
package com.wc.thread;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class CasCounter implements CountBase{
private volatile long value = 0;
private static Unsafe un;
private static long valueOffset;
static
{
try{
un = getUnsafeInstance();
valueOffset = un.objectFieldOffset(CasCounter.class.getDeclaredField("value"));
}catch (Exception e) {
// TODO: handle exception
System.out.println("init unsafe error!");
}
}
@Override
public long getValue() {
// TODO Auto-generated method stub
return value;
}
@Override
public long increment() {
// TODO Auto-generated method stub
long current;
long next;
for(;;)
{
current = value;
next = current + 1;
if(value >= 100000000)
return value;
if(un.compareAndSwapLong(this, valueOffset, current, next))
return next;
}
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
}
测试类和之前类似,只需要用CasCounter类实例化CountBase接口即可;
统计数据如下:
对比两个结果我们可知:
在线程数相对较少的时候,CAS实现比较快,性能优于synchronized,当线程数多于8后,CAS实现明显开始下降,反而时间消耗高于synchronized;
以上结果表明,synchronized是java提供的又简单方便,性能优化又非常好的功能,建议大家常用;CAS的话,线程数大于一定数量的话,多个线程在
循环调用CAS接口,虽然不会让其他线程阻塞,但是这个时候竞争激烈,会导致CPU到达100%,同时比较耗时间,所以性能就不如synchronized了。