乐观锁和悲观锁的使用场景及应用——Java高并发系列学习笔记

Posted 来老铁干了这碗代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乐观锁和悲观锁的使用场景及应用——Java高并发系列学习笔记相关的知识,希望对你有一定的参考价值。

一. 定义

1、乐观锁:顾名思义,对每次的数据操作都保持乐观的态度,不担心数据会被修改,所以不会对数据进行上锁。由于数据没有上锁,这就存在数据会被多人读写的情况。所以每次修改数据的时候需要对数据进行判断是否被修改过。

2、悲观锁:与乐观锁相反,对每次的数据操作都保存悲观的态度,总是担心数据会被修改,所以在自己操作的时候会对数据上锁,防止在自己操作的时候被他人同时操作导致更新丢失。


二. 使用场景

1、乐观锁:由于乐观锁的不上锁特性,所以在性能方面要比悲观锁好,比较适合用在DB的读大于写的业务场景。

2、悲观锁:对于每一次数据修改都要上锁,如果在DB读取需要比较大的情况下有线程在执行数据修改操作会导致读操作全部被挂载起来,等修改线程释放了锁才能读到数据,体验极差。所以比较适合用在DB写大于读的情况。


三. 实现

乐观锁两种常用的实现方式

第一种是使用版本号或者时间戳在表中加个version或updatetime字段,在每次更新操作时对此一下该字段,如果一致则更新数据,数据不等则放弃本次修改,根据实际业务需求做相应的处理。

第二种是CAS方式即Java中的compareAndSwap。CAS操作涉及到三个操作数,内存值(valueOffSet)、期望值(expect)、更新值(update)。当内存值与期望值一致时就会更新数据,反之不操作。


悲观锁三种常用的实现方式

第一种是数据库实现方式。 使用数据库的读锁、写锁、行锁等实现进程的悬挂阻塞等当前操作完成后才能进行下一个操作。

第二种是synchronize的实现方式。 在Java里面可以使用synchronize实现悲观锁。

第三种是使用封装JUC包的实现方式。 在Java中使用LinkedBlockingQueue、ArrayBlockingQueue等JUC的封装包来实现悲观锁,其根本原理是AQS,而AQS是synchronize的升级版。

以上是关于乐观锁和悲观锁的使用场景及应用——Java高并发系列学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

C# 悲观锁和乐观锁的区别以及使用场景。

java中悲观锁和乐观锁的区别

Java -- 每日一问:谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

请说一下悲观锁和乐观锁的区别

乐观锁和悲观锁的使用