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; // 返回新值
}
}
}
以时间换空间、以空间换时间都是实现代码的常用思路,在不同的地方应该使用不同的方式去达到业务需求。