CAS的性能问题
昨天写了一个计数器的类,性能高于JDK,思考了很久,后来被同学点破。
public void increase() {
long before = unsafe.getLongVolatile(this, offset);
while (!unsafe.compareAndSwapLong(this, offset, before, before + 1))
{
before = unsafe.getLongVolatile(this, offset);
Thread.yield();
}
}
有人怀疑是测试的代码问题,后来发现并不是,真正的原因是:在高并发的环境下,CAS修改旧值时经常被其他线程中断,就会进行重试,不断的重试的代价就很高。yield操作能够缓解这个情况,但是也会带来多次上下文切换,在并发没那么高的情况下,反而更浪费资源。
所以JDK在写的Atomic
的类型的时候,应该是考虑到重试一次的代价,小于线程的上下文切换,所以并没有采用yield
操作。