每当我在源码中看到CAS的操作,我总问自己,能不能用在业务项目里面?
需求背景:互斥操作(内存级别),只有一个线程可以获取到临界资源,其他线程直接失败。
入门篇
此篇文章中讨论了CAS可能出现的ABA问题,当然需要结合实际场景来进行分析,是否需要增加时间戳来处理ABA问题。
项目实战
项目实战比较简单,属性中定义AtomicBoolean
变量。然后调用AtomicBoolean的atomicBoolean.compareAndSet(false, true)
方法完成互斥操作,此时进入临界资源只有一个线程(不存在线程安全的问题)。当处理完临界资源后,在finally代码块中再次修改AtomicBoolean
的值。
@Slf4j
public class Test {
private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
private void test() {
//互斥操作
if (atomicBoolean.compareAndSet(false, true)) {
try {
//临界代码逻辑。
} finally {
//线程结束后,恢复AtomicBoolean的值。
atomicBoolean.set(true);
}
}
}
}
其他场景
某个变量我们只想设置一次值。或者某个操作我们只想开启一次,那么可以使用Map<String, AtomicBoolean>操作,针对某个key我们只进行一次CAS操作(在操作后的finally块里面,不修改AtomicBoolean变量)。
网友评论