java web中的线程安全问题
问题描述:
伪代码:
判断redis是否有相应的键值对:
有:
读取redis
没有:
读取数据库
插入redis(列表的插入)
返回
问题
当请求并发时,第一个请求redis未插入而第二个请求也进入了判断,此时第二个请求的判断条件也是"否",所以就会出现redis数据重复的情况.
原因
虽然说对于每一个单独的请求,spring都是新建一个单独的线程来进行处理,但是这并不能够解决上面的问题,究其原因,则是访问了同一个全局数据(可以认为是redis)
解决:
增加一个全局变量,使用synchronize同步方法,伪代码如下
伪代码
全局变量 lock
判断redis是否有相应的键值对:
有:
读取redis
没有:
synchronize(lock)
再次判断redis是否有相应的键值对
有:
读取redis
没有:
读取数据库
插入redis
- 再次判断的原因:加锁只是阻塞了第二个请求的读取数据库/插入redis操作,如果没有再次判断的话,那么当第一个请求释放锁之后第二个请求依旧会再次读取数据库/插入redis,问题依旧存在