背景
java中并发的类基本都在java.util.concurrent这个包中,包括前面介绍的大名鼎鼎的AQS。这个AtomicBoolean也是这个包的类,它支持在单个变量上解除锁的线程安全编程。java.util.concurrent.atomic此包中的类可以将volatile值,字段和数组元素的概念扩展到那些也提供院子条件更新操作的类。后续会一个一个研究。
CAS思想
先看下AtomicBoolean的用法:
1 | boolean compareAndSet(expectedValue, updateValue); |
我们看到了上面提到的一个在java并发中非常重要的一类算法:CAS:compare And set比较设置。我们用上面方法为例来解释下CAS的思想。当内存中可见的值如果和期望的值(expectedValue)一致,则将内存中的值修改为新值(updateValue),并且返回true。该操作是原子性的,意思是线程安全的。当多个线程同时访问某个对象时,如果其中一个线程通过CAS操作获得了访问权限,则其他线程只能在该线程处理完之后才能访问。这类似于同步关键字synchronized但是效率更高,因为没有锁的机制,即使在JDK7之后进行过优化。下面会举例子说明,在多线程中这种原子操作的必要性。例子:
1 | private static volatile AtomicBoolean aFlag = new AtomicBoolean(true); |
上面代码是用一个boolea值来简单判断其它线程是否能进入业务代码执行,我们想看到的是线程1执行完后才能执行线程2,我们来看下结果:
可以看到这个结果是相当混乱,所有线程都抢占了资源。我们再看下使用了AtomicBoolean来看看
1 | public class AtomicDemo { |
结果:
和加锁的效果完全一样。