04.无锁

无锁

锁是一种对操作的同步手段,但是也不是唯一的手段,例如使用空间换时间的思路同样可以解决问题,非阻塞的同步方式也可以达到并发的目的。

最简单的一种非阻塞的同步就是 ThreadLocal 了,每个线程有各自独立的 ThreadLocalMap,在并行计算时无需相互等待。另一种更为乐观的方式是使用 CAS 算法,它有 3 个参数(V,E,N),它总是认为自己的操作可以成功,因此只有在 V 的值等于 E 时,把 V 的值设置成 N;当 V 的值不等于 E,就返回 V 的当前值,然后什么也不做,当多个线程同时使用 CAS 时,只有一个线程会执行成功。

在 java.util.concurrent.atomic 包中有很多支持原子操作的类,都是基于无锁算法实现的,它的性能远远超过普通的有锁操作,例如使用 CAS 算法实现原子操作中的 getAndSet() 方法:

public final int getAndSet(int newValue) {
        for (;;) {                                       // 不停循环直到成功
            int current = get();                         // 获取当前的值
            if (compareAndSet(current, newValue)) {      // 若当前的值未受其他线程影响,则设置为新值
                return current;                          // 返回新值
            }
        }
    }

以时间换空间、以空间换时间都是实现代码的常用思路,在不同的地方应该使用不同的方式去达到业务需求。

上一页