Hi~朋友,点点关注不迷路
多线程在提高我们程序的并发度的同时,也引入线程的安全问题,即多个线程对共享变量的操作是非线程安全的,为了解决线程安全问题,我们引入了锁。锁大体分为两类:
摘要
1. 乐观锁
乐观锁的概念其实很简单,就是在操作一个共享变量时,我们认为多个线程之间没有冲突。
2. CAS
CAS是乐观锁的一种实现,CAS全称是比较和替换,CAS的操作主要由以下几个步骤组成:
上述三个步骤是一个原子性操作,不可以被拆分执行。
3. CAS的优势
CAS是一种无锁操作,不需要加锁,避免了线程切换的开销。
4. CAS的缺点
CAS虽然在低并发量的情况下可以减少系统的开销,但是CAS也有一些问题:
上图是我们在使用CAS的一个基本操作流程。
4.1 CPU开销过大
在我们使用CAS时,如果并发量过大,我们的程序有可能会一直自旋,长时间占用CPU资源。
4.2 ABA问题
假设有个共享变量J,原始值为1。
上述过程,线程B和C已经将变量J的值已经改变了,但是线程A无法发现,依然可以修改共享变量,这就产生了ABA问题。
4.3 共享变量单一
CAS操作单个共享变量的时候可以保证原子的操作,无法操作多个变量。但是在JDK5之后,AtomicReference可以用来保证对象之间的原子性,我们可以把多个对象放入CAS中操作。
5. 如何防止CAS的ABA
三个字:加标志位(version)。
至于标志位可以是自增的数字,也可以是时间戳。通过标志位我们可以精确的知道每次修改。
6. Atomic类
在java.util.concurrent.atomic包下,有一些以Atomic为前缀的类,里面大量使用了CAS操作,如下:
本期的Java 乐观锁(CAS)介绍到这,我是shysh95,我们下期再见!!!