• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

java乐观锁原理与实现案例分析

java 搞代码 4年前 (2022-01-05) 51次浏览 已收录 0个评论

这篇文章主要介绍了java乐观锁原理与实现,结合具体案例形式分析了乐观锁的原理及java使用乐观锁实现自动派单功能的相关操作技巧,需要的朋友可以参考下

本文实例讲述了java乐观锁原理与实现。分享给大家供大家参考,具体如下:

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

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

乐观锁悲观锁的选择:

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

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

 /** * 自动派单 * 只查出一条  返回list只是为了和查询接口统一 * 视频审核订单不派送 * @param paramMap * @return */ public List automaticAssign(Map 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 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 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} 

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

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

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

更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家jav来源gaodai#ma#com搞@@代~&码网a程序设计有所帮助。

以上就是java乐观锁原理与实现案例分析的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java乐观锁原理与实现案例分析

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址