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操作。