注:本篇是对Spring注入单例模式问题的补充
上篇文章已对问题进行详细描述。所以本篇只介绍另一个相关问题。
由于全局变量的使用,再加上Spring的单例模式,该变量就相当于一个单例类,任何线程进来对其的修改都会在其他线程的处理中体现。大部分情况下该情况都会在clear的处理下保存数据不混乱。但是该clear是在两个前提下才有用的,即A线程进来处理完成,B线程才进来处理。或者说是A线程处理中对该全局变量的修改不会实时的同步到静态存储区中去,在A线程处理完成前A对全局变量的修改结果不会体现在其他线程的处理中。由于使用全局变量是前人写的方案进行的处理,所以后来者看到这种写法时都奉行了一个原则 - - - 天下代码一大抄!
那么问题来了!当本人接触新需求时,很明显也沿用了之前的处理方法。而且想当然的认为是这样的原理:即A线程进来时获取的只是该全局变量(对象)的一个镜像缓存,修改的也是该缓存,只有当A线程处理完后才会提交该缓存,然后才会影响到静态存储区的值。这也就应正了上面的第二个前提。然而事实并非如此。有爱思索又上进的同事觉得这样的处理方法有问题,过来问了我。当时看了一下自己的代码依稀记得之前是测试过的,然后解释时认为获取的就是对象的一个镜像。再后来闲下来又测才发现居然是实时修改的,也就是说获取的并不是该全局变量的一个镜像。然后就发现如果出现并发问题,A线程在处理中,B线程进来把数据修改了,那么A中的处理就有可能用了B请求的数据。指不定出什么幺蛾子。于是呼,报请领导,又一番测试,毙了老方案,提了一个新方案,把那些全局变量改成局部变量。还好生产环境中用这种模式的功能并发不太大,而且公司服务器性能还阔以,没造成大的损失。
到此算是告一段落。但是关于获取对象镜像的情况仍需再了解。