CAS和原子操作笔记
2023-07-03 12:30:21 5 举报
CAS和原子操作笔记
作者其他创作
大纲/内容
CAS是通过cpu所支持的cas指令来实现的原子操作
java中的Atomic系列的原子操作类的实现利用了cas+循环重试来实现
CAS实现原子操作的三大问题
ABA问题:
就是在更新时发现值为A没有变化,但是其他线程可能吧值从A改为B,然后又从B改为A,看似没没有变化,其实值已已经发生了改变
解决方案:
增加版本标记,或者维护版本号
CAS长时间自旋引起的开销问题:
在并发量高的场景下,CAS会长时间失败重试,浪费cpu资源
解决方案:
可以尝试使用锁
CAS只能保证一个共享变量的原子操作:
在对多个共享变量操作时,循环CAS无法保证操作的原子性
解决方案:
可以把多个变量合并成一个共享变量来操作,比如i=2,j=3可以合并成ij = 23
可以把多个变量放在一个对象里来进行原子操作
线程安全性:
我们的代码在并发的场景下,总能表现出正确的行为
类是线程安全的定义:
当多个线程访问某个类的时候,不管运行时环境采用何种调度方式或者这些线程将如何交替进行,并且在调用代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么这个类就是线程安全的
具体如何实现:
线程封闭:
把对象封装到一个线程里,只有一个线程能获取此对象
栈封闭:
·使用局部变量,局部变量存在线程栈中,多个线程调用同一个方法会生成多个栈帧,局部变量不会共享
ThreadLocal:
是实现线程封闭最好的方法,ThreadLocal内部维护了一个Map,key为线程的名称,Value是我们需要封闭的对象,每个线程中的对象都对应着Map中的一个值
无状态的类:
没有任何成员变量的类,就叫无状态的类,这种类一定是线程安全的,
让类不可变:
一个类的所有成员变量都是私有的且都使用final关键字修饰,如果成员变量是一个对象,name这个对象所对应的这个类需要时安全的才可以
加锁和CAS:
使用synchronized关键字内置锁,使用显式锁,使用各种原子变量,更新操作使用CAS机制等
死锁的产生条件以及解决方法:
多个进程争夺多个资源
争夺资源的顺序不对
解决方案:
内部通过顺序比较,确定拿锁的顺序,比如通过hash取值比较大小
争夺者对拿到手的资源不放手
解决方案:
采用尝试拿锁的机制,比如tryLock(),拿不到第二把锁就解开第一把锁
可能导致活锁问题:几个线程同时拿不到锁同时释放的问题
解决方案:每个线程休眠随机数,错开拿锁时间!
0 条评论
下一页