简单说说乐观锁。乐观锁是相对于悲观锁而言。悲观锁认为,这个线程,发生并发的可能性极大,线程冲突几率大,比较悲观。一般用synchronized实现,保证每次操作数据不会冲突。乐观锁认为,线程冲突可能性小,比较乐观,直接去操作数据,如果发现数据已经被更改(通过版本号控制),则不更新数据,再次去重复 所需操作,知道没有冲突(使用递归算法)。

因为乐观锁使用递归+版本号控制  实现,所以,如果线程冲突几率大,使用乐观锁会重复很多次操作(包括查询数据库),尤其是递归部分逻辑复杂,耗时和耗性能,是低效不合适的,应考虑使用悲观锁。

乐观锁悲观锁的选择:

乐观锁:并发冲突几率小,对应模块递归操作简单    时使用

悲观锁:并发几率大,对应模块操作复杂 时使用

下面给出一个乐观锁实例:

 /*** 自动派单* 只查出一条    返回list只是为了和查询接口统一* 视频审核订单不派送* @param paramMap* @return*/public List<AutomaticAssignDto> automaticAssign(Map<String, Object> paramMap){//派送规则String changeSortSet = RedisCacheUtil.getValue(CACHE_TYPE.APP, "changeSortSet");if (StringUtils.isBlank(changeSortSet)) {changeSortSet = customerManager.getDictionaryByCode("changeSortSet");if (StringUtils.isNotBlank(changeSortSet)) {RedisCacheUtil.addValue(CACHE_TYPE.APP, "changeSortSet", changeSortSet,30,TimeUnit.DAYS);} else {changeSortSet = ConstantsUtil.AssignRule.FIFO; // 默认先进先审}}AutomaticAssignDto automaticAssignDto = new AutomaticAssignDto();automaticAssignDto.setChangeSortSet(changeSortSet);automaticAssignDto.setUserTeam(CommonUtils.getValue(paramMap, "userTeam"));List<AutomaticAssignDto> waitCheckList = automaticAssignMybatisDao.automaticAssignOrder(automaticAssignDto);if(waitCheckList != null && waitCheckList.size()>0){automaticAssignDto = waitCheckList.get(0);automaticAssignDto.setSendStatus(ConstantsUtil.SendStatus.SEND);automaticAssignDto.setBindTime(new Date());automaticAssignDto.setUserId(Long.parseLong(paramMap.get("userId").toString()) );int sum = automaticAssignMybatisDao.bindAutomaticAssignInfo(automaticAssignDto);if(sum == 1){return waitCheckList;}else{//已被更新 则再次获取return automaticAssign(paramMap);}}else{return null;}}

对应更新的sql:

 <update id="bindAutomaticAssignInfo" parameterType="com.star.manager.dto.apply.AutomaticAssignDto">UPDATE t_automatic_assign SET  SEND_STATUS = #{sendStatus} ,BIND_TIME = SYSDATE() ,LOCKED_FINISHTIME = SYSDATE(),USER_ID = #{userId} ,VERSION = VERSION + 1, UPDATE_DATE = SYSDATE()WHERE SLT_ACCOUNT_ID = #{sltAccountId} AND VERSION = #{version}</update>  

简要说明:表设计时,需要往表里加一个version字段。每次查询时,查出带有version的数据记录更新数据时,判断数据库里对应id的记录的version是否和查出的version相同。若相同,则更新数据并把版本号+1;若不同,则说明,该数据发送并发,被别的线程使用了,进行递归操作,再次执行递归方法,知道成功更新数据为止。

上述automaticAssign方法即实现了一个乐观锁,作用是冲数据库里更新一条数据病返回前端。如果并发率大,一次请求可能则会重复执行很多次automaticAssign,则性能低。如果并发很乐观,用户请求少,则不需要用synchronized,多线程时性能高。

在此只是简单说说,详细概念等需另行查阅相关资料。

java乐观锁实现案例相关推荐

  1. Java乐观锁的实现原理和典型案例

    Java乐观锁的实现原理 什么是乐观锁? 在并发编程中,多个线程同时对同一资源进行操作时,需要使用锁来保证数据的一致性. 乐观锁与悲观锁是两种不同的锁机制. 悲观锁会在整个操作期间占用资源的独占性,以 ...

  2. Java 乐观锁和悲观锁

    文章目录 Java 乐观锁和悲观锁 1.悲观锁 2.乐观锁 2.1 CAS 2.2 模拟CAS算法 2.3 JUC 2.4 CAS中的ABA问题 2.5 使用CAS会引发的问题 Java 乐观锁和悲观 ...

  3. java乐观锁实现_Java 乐观锁原理与实战演练

    原标题:Java 乐观锁原理与实战演练 一. 前言 最近在做一个简单审批流程的项目,由于只有固定二级审批所以没有工作流组件,然后就遇到一个审批节点捞单时候,多个人同时审批时候如何保证业务正常运行的问题 ...

  4. Java乐观锁的实现原理(案例)

    锁,当多个事务同时对数据库表中的同一条数据操作时,如果没有加锁机制的话,就会产生脏数据(duty data). 有2种机制可以解决这个问题:就是悲观锁和乐观锁了. 这里我们使用乐观锁,通过案例代码来实 ...

  5. java 乐观锁 实例_JAVA乐观锁实现-CAS(示例代码)

    是什么 全称compare and swap,一个CPU原子指令,在硬件层面实现的机制,体现了乐观锁的思想. JVM用C语言封装了汇编调用.Java的基础库中有很多类就是基于JNI调用C接口实现了多线 ...

  6. Java 乐观锁 悲观锁

    一.乐观锁.悲观锁定义 乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据.因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行 ...

  7. java 乐观锁和悲观锁,Threadlocal

    7.乐观锁和悲观锁 悲观锁(Pessimistic Lock)顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会 block 直到它拿到 ...

  8. Java乐观锁%悲观锁

    1.乐观锁 尝试去获得一把锁,无论获得还是无法获得立刻返回True/False 不会阻塞进程,使用此锁可在获取锁的过程中完成其它操作.如下例子演示了在线程1获得了锁之后,线程2使用trylock()可 ...

  9. java乐观锁简单实现

    这里用版本号实现 sql CREATE TABLE `t_optimistic` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(255 ...

最新文章

  1. [Treap]JZOJ 4737 金色丝线将瞬间一分为二
  2. oauth2 增加token 返回参数_一张图搞定OAuth2.0
  3. 从零玩转HTML5前端+跨平台开发上
  4. bcb异常处理显示错误行号_SpringBoot系列(七)- springboot 错误异常处理统一办法
  5. SCSS 实用知识汇总
  6. 交付方式 saas_扩展和交付SaaS启动的最佳方法
  7. phpcms模型缓存更新原理分析(转)
  8. numpy matrix 矩阵对象
  9. git 合并其他分支代码到自己的分支
  10. Android核心分析 之二方法论探讨之概念空间篇
  11. EasyUI Datagrid换页不清出勾选方法
  12. python1到20的阶乘求和_Python的阶乘求和
  13. 最全的react视频【黑马程序员】--第一章 react介绍
  14. bulma css 中文,Bulma CSS – 开始
  15. vcpkg: bootstrap-vcpkg.bat下载失败问题
  16. 机器学习 | 台大林轩田机器学习基石课程笔记5 --- Training versus Testing
  17. UTC和东八区时间转换(python)
  18. Vue3初识 学习记录(一)
  19. Docker基础-使用Dockerfile创建镜像
  20. 奇瑞鲍思语将十万级无界Pro推出市场

热门文章

  1. 七、熵编码算法(1):基础知识
  2. 亚马逊构建俄勒冈数据中心园区
  3. 让信息流广告成为ROI狙击手的终极全策略!
  4. mysql 查询多个记录查询_MySQL多表数据记录查询详解
  5. 华为端口隔离实现原理及配置命令
  6. 各类Excel表格批量合并问题的实现思路与案例
  7. Down-Sampling 降采样(Verilog)
  8. R700指令集架构参考手册——第一章:介绍
  9. 【网络安全】EAP协议
  10. HoloLens开发