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了。

相关文章
相关标签/搜索