社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
总是认为不会产生并发的问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般使用版本号机制或CAS机制来实现!
CAS是乐观锁的一种实现方式,是一种轻量级的锁!
原理:线程在读取数据时不进行加锁,在准备写回数据时,先去查询原值,操作的时候比较原值是否被修改,若为被修改则写回,否则,重回新执行读取流程。
因为CAS操作长时间不成功的话,会导致一直自旋,相当于死循环,造成CPU消耗过大!
总是假设最坏情况,每次取数据时都认为其他线程会修改数据,所以都会加锁,当其他线程想要访问数据时,都要挂起等待。
synchronized,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。
你可以看到在对象头中保存了锁标志位和指向 monitor 对象的起始地址,如下图所示,右侧就是对象对应的 Monitor 对象。
当 Monitor 被某个线程持有后,就会处于锁定状态,如图中的 Owner 部分,会指向持有 Monitor 对象的线程。
另外 Monitor 中还有两个队列分别是EntryList和WaitList,主要是用来存放进入及等待获取锁的线程。
如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行。
1.响应速度:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁
2.冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率,如果冲突频率大,乐观锁会需要多次重试才能成功,代价比较大
3.重试代价:如果重试代价大,建议采用悲观锁
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!