在高并发环境下,再次认识java 锁

简介: 在高并发环境下,再次认识java 锁

1.背景

线上部署的应用,偶尔会出现,数据读取出来为空的情况,但是通过打印日志,发现数据确实是存在的。

日志文件:

对应代码:

2.系统架构梳理

tagId2NameMap 是通过一个定时任务去更新的,即:updateTagIdMapping 函数,

本来 tagId2NameMap 是HashMap

3.问题定位排查

(1)以为是不安全的原因导致的,改为ConcurrentHashMap,改为ConcurrentHashMap,还是会出现一样的问题

(2)增加日志,发现是在发生updateTagIdMapping 更新时间和 getTagName 函数时间非常接近的时候,在几毫秒的差异时候,会出现上述问题。

怀疑是tagId2NameMap 在clear 之后,数据还没有完全addAll进去。

4.解决思路

解决方案一:

通过加锁的方式来进行处理,上述业务场景,非常明显,适合读写锁,读的QPS 是较高的,而写的QPS非常低,是通过定时任务来定时进行配置。

private final ReentrantReadWriteLock updateLock = new ReentrantReadWriteLock();

在更新的地方加写锁

在读取的地方加读锁

最终没有出现上述问题。

解决方案二:

用将数据添加到tmp 临时变量中,再进行赋值替换

问题定位难点:本地较难复现,刚好更新时间和读取时间一致。本地很难出现和线上一样的QPS,线上流量高峰期QPS有接近6000

读写锁原理和使用参考:

相关文章
|
2月前
|
存储 监控 固态存储
在高并发环境下,如何优化 WAL 的写入性能?
在高并发环境下,如何优化 WAL 的写入性能?
|
3月前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
50 2
|
1月前
|
缓存 Java
java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁
本文介绍了几种常见的锁机制,包括公平锁与非公平锁、可重入锁与不可重入锁、自旋锁以及读写锁和互斥锁。公平锁按申请顺序分配锁,而非公平锁允许插队。可重入锁允许线程多次获取同一锁,避免死锁。自旋锁通过循环尝试获取锁,减少上下文切换开销。读写锁区分读锁和写锁,提高并发性能。文章还提供了相关代码示例,帮助理解这些锁的实现和使用场景。
java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁
|
1月前
|
Java 开发者
Java 中的锁是什么意思,有哪些分类?
在Java多线程编程中,锁用于控制多个线程对共享资源的访问,确保数据一致性和正确性。本文探讨锁的概念、作用及分类,包括乐观锁与悲观锁、自旋锁与适应性自旋锁、公平锁与非公平锁、可重入锁和读写锁,同时提供使用锁时的注意事项,帮助开发者提高程序性能和稳定性。
66 3
|
1月前
|
Go 计算机视觉
在Golang高并发环境中如何进行协程同步?
在此示例中,使用互斥锁来保护对共享计数器变量 c 的访问,确保并发的 HTTP 请求不会产生数据竞争。
46 3
|
1月前
|
缓存 监控 Java
Java 线程池在高并发场景下有哪些优势和潜在问题?
Java 线程池在高并发场景下有哪些优势和潜在问题?
|
2月前
|
Java
Java 中锁的主要类型
【10月更文挑战第10天】
|
2月前
|
设计模式 缓存 Java
Java高并发处理机制
Java高并发处理机制
30 1
|
3月前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
51 5
|
3月前
|
Java Linux Python
Linux环境下 代码java调用python出错
Linux环境下 代码java调用python出错
69 4