话说栈长前阵子写了一个功效,测试 0 bug 就上线了,上线后也运行好好的,好多天都没有人反馈bug,超爽。。

不出问题还好,出问题就是大问题。。

最近有个客户反馈某些数据杂乱问题,看代码死活看不出什么问题,很诡异,再仔细看代码,原来是一个全局变量的问题,导致在并发情形下泛起了线程不平安的问题,事后被同事们打脸!!!

慎用全局变量,我在公司一直在强调,没想到这么低级的问题居然发生在自己身上,说起来真的内疚啊。。

最最先使用的是 Spring 注入工具的方式:

@Autowired
private Object object;

由于 Spring 默认是单例,以是这样写是没有问题的,厥后随着营业的生长,需要多个差别的营业实例,我改成了这种方式:

@Setter
private Object object;

这个 @Setter 是 Lombok 的注解,用来天生 setters 方式,现在想起来,真是低级啊,同时操作的情形下,这个工具肯定会泛起笼罩的情形,从而导致上面说的问题。

写了一个这么低级bug,我也不怕不好意思发出来,人人都谨记一下吧。

另外,我再总结几个慎用全局变量的场景:

1、SimpleDateFormat

SimpleDateFormat 克制界说成 static 变量或者全局共享变量,由于它是线程不平安的,都被写进阿里巴巴的《Java开发手册》里了:

为什么说 SimpleDateFormat 不是线程平安的呢?

来看下它的 format 方式源码:

可以看到 calendar 变量居然也是全局变量,多线程情形下就会存在设置脏变量的情形。

以是,若是要用 SimpleDateFormat,就在每次用的时刻都建立一个 SimpleDateFormat 工具,做到线程间隔离。

2、资源毗邻

资源毗邻包罗数据库毗邻、FTP毗邻、Redis毗邻等,这种也要慎用全局变量,一量使用全局变量,就会遇到以下问题:

1)关闭毗邻的时刻,就可能把别人正在操作的毗邻给关了,导致其他线程的营业中止;

2)由于是全局变量,建立的时刻可能会建立多个实例,在关闭毗邻的时刻,就可能只关闭了一个工具的毗邻,造成其他毗邻没有被关闭,最后导致毗邻耗光系统不可用;

3、数字运算

这也是个很经典的问题了,若是要用多线程对一个数字举行累加等其他运算处置,万万不要用全局基础类型的变量,如下所示:

private long count;

多线程情形下,某个线程获取到的值可能已经被其他线程修改了,最后获得的值就不准确了。

固然,上面的示例可以通过加锁的方式来解决,也可以使用全局的原子类(java.util.concurrent.atomic.Atom*)举行处置,好比:

private AtomicInteger count = new AtomicInteger();

注重,这种原子类使用全局变量就没有线程平安的问题,它使用了 CAS 算法保证了数据一致性。

不外,阿里推荐使用LongAdder,由于性能更好:

java.util.concurrent.atomic.LongAdder

4、全局session

来看下面的例子:

@Autowired
protected HttpSession session;

全局注入一个 Session 工具,在 Spring 中,这样全局注入使用上面是默认没问题的,包罗 request, response 工具,都可以通过全局注入来获取。

这样会存在线程平安性吗?

不会!

使用这种方式,当 Bean 初始化时,Spring 并没有注入真实工具,而是注入了一个署理工具,真正使用的时刻通过该署理工具获取真正的工具。

而且,在注入此类工具时,Spring使用了线程局部变量(ThreadLocal),这就保证了 request/response/session 工具的线程平安性了。

详细就不展开了,详细的先容及测试人人可以点击这个链接查看这篇文章。

既然是线程平安,但也得小心,若是我在方式中自动使 session 工具失效并重建了:

session.invalidate();
session = request.getSession();

这样,session工具就变成了真实工具了,不再是署理工具,就变成了文章最最先的时刻我说的那种多线程平安问题了,若是线上泛起 session 会话杂乱,用户 A 就可能看到用户 B 的数据,你想想可不恐怖?

以是,纵然可以这样使用,也得万万小心郑重,最好是在方式级别使用这些工具。

总结

今天,栈长总结了一下我是怎么写出这个全局变量的低级 bug,也总结了下慎用全局变量的 4 种情形,信赖人人多若干都遇到过类似的问题,希望能辅助人人少踩坑。

全局变量虽好,但我们也得郑重使用啊,一定要思量是否引起多线程平安问题,否则会引起重大问题。

你还遇到过哪些全局变量的问题,迎接留言分享哦!

推荐去我的博客阅读更多:

1.Java JVM、聚集、多线程、新特征系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架构、阿里巴巴等大厂最新面试题

以为不错,别忘了点赞+转发哦!

,

Allbet手机版下载

欢迎进入Allbet手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

Allbet Gaming声明:该文看法仅代表作者自己,与阳光在线无关。转载请注明:allbetgmaing下载:写了个全局变量的bug,被同事们打脸!!!
发布评论

分享到:

皇冠注册平台:02/15午间论市:手艺破位加速下跌将到来
1 条回复
  1. 环球UG注册
    环球UG注册
    (2020-08-26 00:02:47) 1#

    平心在线欢迎进入平心在线官网(原诚信在线、阳光在线)。平心在线官网开www.px111.net放平心在线会员登录网址、平心在线代理后台网址、平心在线APP下载、平心在线电脑客户端下载、平心在线企业邮局等业务。百看不厌呢

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。