今天使用synchronized和java unsafe cas接口對比了下同一個操做下的的相關性能,java
爲後面多線程狀況下使用synchronized同步阻塞方式或者是unsafe cas非阻塞作了一個參考。性能優化
測試用例:多線程
啓用多個線程進行計數相加到一億,首先是synchronized方式;ide
計算類以下:性能
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個線程的時候,性能又有一點提高。this
若是換成CAS實現多線程累加數爲一億,時間又會怎麼樣呢,咱們先來看下測試代碼:spa
計算類以下:線程
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了。