天天看點

CSA和synchronized使用的場景

csa原理

csa的原理是對比期望值和實際值是否相等,不相等就一直循環,直到成功.

synchronized的原理

synchronized的原理通過jvm的鎖實作每次隻允許一個線程執行.

代碼驗證兩者的性能

csa代碼

package csa;

import java.lang.reflect.Field;

import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.context.annotation.Bean;

import sun.misc.Unsafe;

public class CsaIncr {

private volatile int count = 0;

private static long valueOffset;

private static Unsafe unsafe;

static {

Field theUnsafeInstance;

try {

theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");

theUnsafeInstance.setAccessible(true);

unsafe = (Unsafe) theUnsafeInstance.get(Unsafe.class);

valueOffset = unsafe.objectFieldOffset(CsaIncr.class.getDeclaredField("count"));

} catch (Exception e) {

e.printStackTrace();

}

}

public int getCount() {

return count;

}

public void increment() {

int cu;

int next;

for (;;) {

cu = count;

next = cu + 1;

if (count > 100000000) {

break;

}

boolean compareAndSwapInt = unsafe.compareAndSwapInt(this, valueOffset, cu, next);

if (compareAndSwapInt) {

break;

}

}

}

}

線程數 8 16
時間ms 9240 14098

synchronized代碼

import sun.misc.Unsafe;

public class SyIncr {

private volatile int count = 0;

public int getCount() {

return count;

}

public synchronized void increment() {

if (count > 100000000) {

return;

}

++count;

}

}

線程數 8 16
時間ms 4910 4871

從代碼可以看出csa失敗就進入循環,直到成功,在這期間會一直占用cpu資源,線程越多,失敗幾率越高,cpu占用時間越長,當cpu100%在增加線程性能就會下降.

但是synchronized單線程執行,等待線程會阻塞,不會消耗cpu,但是會耗時在核心到使用者态的線程切換,這部分時間是固定,

總結:并發線程一般少于6個,适合用csa.大于6個适合用synchronized

繼續閱讀