并发引起的java.lang.NullPointerException

问题背景:

我有一段程序,大量地、并发地发送SNMP告警。这里所谓的并发,就是有很多的定时任务(java.util.Timer),它们行为独立,各自创建SNMPTrap实例,各自通过SNMPTrap 发SNMP告警。


问题描述:

多个Timer长时间(月级)运行时,经常莫名奇妙某个Timer就死掉了,死掉前抛出java.lang.NullPointerException。


问题发现:

经过分析,发现集中、大量、并发地创建SNMPTrap实例时,不同Timer线程虽然各自执行其new SNMPTrap()语句,但在并发情况下,如果两个new语句执行时间足够近,会得到同一份(内存地址相同的)SNMPTrap实例。


我是怎么发现这个问题的呢?通过分析空指针发生时的日志,发现在抛出java.lang.NullPointerException的日志前面,总会出现两次或多次的类似下面的打印信息:

……

org.snmp4j.Snmp@1dd49247
……
org.snmp4j.Snmp@1dd49247

……

java.lang.NullPointerException

……

@之前是类的全限定类名,@之后是类实例的hashCode()值——这个值的默认实现,是根据类实例的内存地址计算出来的。亦即虽然在不同的线程中new了两个实例,但因为时间间隔太近,两份实例指向了同一个内存地址……于是就乱套了,抛出了空指针异常(在这里面,GC的不定时执行可能也起了一定作用)。


问题解决:

重用SNMPTrap,不在大并发的Timer线程中new其实例 。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值