多线程改变某变量值时,大多用synchronize加锁,效率较低,在jdk1.5之后加了原子类,例如:AtomicInteger(无锁、自旋锁)
AtomicInteger i = new AtomicInteger(); i.incrementAndGet(); |
无锁实现多线程自增
实现原理:CAS技术(compare and swap/compare and exchange)
无锁状态下保证多个线程对一个值的更新
多线程状态并在无锁的时候,保证线程一致性去改动某一个值这就是CAS技术。
ABA问题:在比较当前值后/修改值前,另一线程也同时把当前值取走并修改与当前值相等的情况
解决ABA问题:对每个当前值加version,任何线程对当前值修改,都要修改版本号,当前线程取走当前值修改时也取走当前版本,在比较值的同时也比较版本号
如果ABA不产生影响,不用考虑
API(源码跟踪)
asm(汇编语言):
cmpxchgl(compare and change):比较并交换,java CAS操作在底层上有对应的汇编指令,硬件级别直接执行
LOCK_IF_MP(MP:multiProcessors 多个CPU)
最终执行指令:lock cmpxchg 指令
如果确保CAS在比较后/写入前时的值不被其他线程修改?
首先:cmpxchg是不能保证数据的原子性(CAS支持执行cmpxchg比较交换底层指令,但该指令非原子性)
Lock:当执行后面的指令时,其他CPU不能对后面的值进行操作