工作久了,就会遇到各种稀奇古怪的bug,这不今天就遇到一个最普通的空指针异常,奇怪的是它出现的位置怎么看也不可能会出现空指针异常。
- 用arthas定位到,出现异常的方法是HashSet里面的isEmpty方法。这个方法就一行,只有一个可能就是map为null。

- HashSet里面的map怎么会被设置成null呢,并没有方法能把map设置成null,那就只能是非常规手段(反射)造成的,通过搜查,并没有这样的代码。那还有一个可能就是并发问题,这个set集合是一个对象里面的属性,这个对象是个缓存,多个线程都能获取到同一个对象,所以是有线程安全问题的。问过AI,也是有并发问题的可能。

- 搜查完使用这个属性的地方,并没有对这个属性进行修改或者重新指向。
- 最后发现是get方法里面的问题
private HashSet set = new HashSet(); public HashSet getSet() { if (CollUtil.isEmpty(set)) { set = new HashSet(); } return set; }getSet方法被多个线程调用,set属性刚好是空集合,所以每次都会执行set = new HashSet();这一行代码,当一个线程正在执行CollUtil.isEmpty(set)这个方法,另一个线程正在执行set = new HashSet()这个方法,就有可能出现HashSet里面的isEmpty方法空指针异常。
1447

被折叠的 条评论
为什么被折叠?



