Java多线程、并发时使用Synchronized(同步锁)解决资源竞争问题

来源:互联网 发布:二维码美化软件是什么 编辑:程序博客网 时间:2024/05/18 03:56


业务场景:地图绘制时将绘制好的地图信息(如坐标、关联任务信息等等)保存到DB同时在Redis中保存一份缓存数据。

问题描述:前端页面显示时发现有重复数据,如:同一个地图信息展示了两次。

解决思路:先是断点检查了一下代码,发现程序正常执行,检查DB物理数据库发现数据正常,检查Redis缓存数据发现将DB中的数据在Redis中存了两次。(DB中共144条数据,Redis中288条数据)。

将Redis缓存数据清空,断点设置在Redis缓存数据保存处。发现同时有两次请求。

                查找前端加载页面,发现jsp页面中的ajaxx同时加载了两次保存缓存数据的方法。

分析问题:开始以为是redis事物问题,于是开始添加Redis事物。 如:Transaction tx = jedis.multi(); 详细讲解博客:http://blog.csdn.net/s296850101/article/details/52416043

添加完Redis 事物后还是没解决问题,原因:即使添加事物,程序也是一条一条进入事物、保存数据、关闭事物。

仔细调试代码后发现是并发引起的,如下图:(原程序没有关键字synchronized)   在不加锁时,两条请求同时进入下图方法中,下图程序中的redis判断缓存Key是否存在的机制不起作用(如图中的第一个红框处)。第一个请求将144条数据放入Reids(调用rpush命令)

Redis Rpush 命令用于将一个或多个值插入到列表的尾部(最右边)。详细:http://www.runoob.com/redis/lists-rpush.html

如rpush解释的一样,第二调请求会将144条数据插入到第一个请求保存完的list后面,这样就出现了重复数据共288条。

解决办法,给方法加上synchronized锁。如下图。




解决问题过程中收集了几个博主的文章,有更好的见解或好的文章,欢迎留言:

https://www.cnblogs.com/danbing/p/5319820.html

http://blog.csdn.net/yangzhaomuma/article/details/51236976

阅读全文
0 0
原创粉丝点击