关于工作中的一些总结

今天和公司某大佬一起研究了一个解决方案,将在此过程中收获的新知识记录一下。


事情起因于一个bug,场景如下:

服务端通过某特定记录标识向客户端发起数据查询,但出现了接收到重复数据的情况。

分析原因如下:

由于某些数据量庞大,在下一轮查询开始后,仍然没有结束。而此时按照原本的业务逻辑就可能会出现相同指令重复发送的情况,这个错误相对比较隐蔽,实际上在代码中为了避免指令重复,每次发送指令后,都会在缓存中存入一个特定标识。但是在多线程的场景下,有时可能会在标识成功写入缓存之前,进行标识存在与否的判断,这就导致了这个bug的出现。

同步块:

最终采用java中同步关键字来解决这个问题,为了减少同步处理对于性能的不必要损耗,并不是所有线程共用一个线程锁,而是会导致bug的线程用一个线程锁,互不干涉的线程则不加锁。

按照我的习惯这些锁统一放在一个集合中存储,然后集合作为类的成员变量而存在。

但是,大佬使用了静态内部类来存放这个线程锁集合,仔细一思考,这种写法当没有使用到这个集合的时候,它并不会被初始化,还是有道理的。

最近读到了一篇文章告诫广大码农不要过度依赖redis中的过期机制,给出的理由大致是redis中数据过期并不是十分准确的,比如你设置两分钟过期,然而可能两分零一秒这个数据的过期才被监听到。

读到这里就想起了之前在网上看到的一篇文章简述了redis中的数据过期机制,我自己总结了一下,大意就是会定期检测一下数据是否过期,当数据被使用到时,也会检测数据是否过期。

把这两篇文章结合起来思考就不难理解为什么会有过期延迟的情况发生了,也就是说并没有使用到过期数据,也暂时没有被定期检测到过期,但实际上按照设置的时间已经算是过期了。

文章中还提到了当数据量大的情况下,这种延迟的情况会比较明显。

关于redis这一部分我没试过,以后有合适的机会的时候再观察一下这些结论的正确性。

原文地址:https://www.cnblogs.com/wxdmw/p/13937077.html