Thread Dump分析线程竞争
并不是用了线程池、多线程,就可以带来更高的性能的,总有些地方需要一个锁进行同步。
JAVA 中的synchronized就是一种悲观锁。
本次分析Thread Dump发现性能问题是一个OOM问题中的消费速率过慢的问题。
截图
- 对于线程池pool-20来说,一共12个线程,一个处于running,一个waiting,还有10个处于blocking的状态,基本就是同步进行了,无意义的多线程了。
- 发现#getData方法是synchronized修饰的,从类名也可以看出来这是一个手写的本地缓存,存在ConcurrentHashMap中,并将其更新以文件的方式刷入磁盘。
具体代码就不能贴了,所以这里只是记录思路!!!
- 对于get方法,都是直接从ConcurrentHashMap中取的,它本身就用了CAS来确保线程安全,没有必要用synchronized进行修饰。
- 对于set方法,一步是修改入ConcurrentHashMap,一步是刷新文件。他同样是用了synchronized进行修饰。毫无疑问,又没用上ConcurrentHashMap的分段乐观锁的性能优势,又会全部阻塞。
- 对于2中提到的刷文件,其实可以交予一个ScheduledThreadPoolExecutor创建的一个定时线程来进行刷新缓存,当一致性要求没那么高的时候,即使宕机或者应用dump等等都不会带来多少问题。
- 本地缓存有guava等开源框架,有空还是要学习一下源码的。