java使用synchronized和cas性能对比
今天使用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了。
posted on 2018-03-12 20:57 willowWind 阅读(3482) 评论(3) 编辑 收藏 举报