天天看点

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

继续阅读