java使用synchronized和cas性能對比

今天使用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了。

相關文章
相關標籤/搜索