其实我想说的意思就是上图时间线表明的问题,即便是A线程使用双删除,但是在高并发情况下是否存在其他线程在线程B存入旧数据(就是M=400)到A线程再次删除这个时间段内有其他线程读取M,然后拿脏数据的M做判断去进行后续操作呢?
假如这种情况是存在的,我的解决方案是定义一个public static final Map redisKeyMap = Maps.newHashMap();然后把放入redis的键全部放入这个集合,每次操作缓存时对相应的key加锁(不是说只要操作缓存就加锁),即synchronized (redisKeyMap.get(key1)){},保证A线程操作指令的一个原子性,以及A、B线程之间的顺序性,即下图所示:
备注:关于评论区老哥说的这时候D、E、F线程也读取不了缓存的情况,其实我们可以把线程A、B加锁的时间点放在读缓存后(其他线程也是如此),查询数据库前来减少临界区代码,可以提升并发量。
附上一个公式:
Tips: 临界区都是串行的,非临界区都是并行的,用单线程执行临界区的时间/用单线程执行(临界区+非临界区)的时间就是程序串行百分比,所以并发编程在不影响数据安全的情况下应尽可能减小临界区代码量,从而充分利用cpu使用率提升并发效率。