这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
原子操作
假定有两个操作A和B(A和B可能都很复杂),如果从执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。
如何实现原子操作
-
锁
当一个线程拥有锁的时候,访问同一资源的其它线程需要等待,直到该线程释放锁
-
CAS指令
如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少。循环CAS就是在一个循环里不断的做cas操作,直到成功为止
锁机制的缺点
- 如果被阻塞的线程优先级很高很重要无法处理
- 如果获得锁的线程一直不释放锁会造成死锁
- 如果有大量的线程来竞争资源,那CPU将会花费大量的时间和资源来处理这些竞争,同时,还有可能出现一些例如死锁之类的情况
最后,其实锁机制是一种比较粗糙,粒度比较大的机制
CAS的原理
如果这个地址上的值和期望的值相等,则给其赋予新值,否则不做任何事儿,但是要返回原值是多少。循环CAS就是在一个循环里不断的做cas操作,直到成功为止。
CAS存在的问题
-
ABA问题 简单地描述,就是值被中途修改过的问题。如果我们不关心值是否被改动过,只关心结果,那其实也无所谓。
解决方法:加个版本戳
-
开销问题
当资源竞争足够大,成千上亿个线程去同时争一个资源,那其实大部分时候,大部分的线程都是在compare和重新获取的过程中,就会造成CPU的繁忙
-
只能保证一个共享变量的原子性
CAS的机制就是比较并且交换,只是针对一个资源
解决办法:把多个共享变量合并成一个共享变量来操作