今天很low逼的发现,一直以来以为在visual studio 编译器中, static定义的函数内变量是线程安全的, 今天项目中的一个单例测试问题给了我一课,也给大家分享一下,避免像我这样半桶水的再掉坑里。代码是这么写的:
这个单例代码已经忘了是哪位老前辈教我的了 , 网上看了一发,犯这个错误的人还是不少的。
先抛出结论:这个单例写法不是线程安全的。
测试中发现的问题, 于是要验证分析一波, 编译器到底是怎么处理这个写法的才导致了这个写法的非线程安全的结果, 做如下测试代码:
直接VS中运行起来,在断点处断下, 右键 - 转入反汇编模式,得如下编译器实现代码:
参看上面的几句注释代码发现, 编译器在静态变量的地址紧挨着的四字节位置设置了一个保护标志位,内存布局如下:
所以,多线程问题的引入就是这个标志位没有任何保护,所以导致 this 指针的这个位置也没有了保护,因此引入了 getInstance 的多线程问题
这个单例代码已经忘了是哪位老前辈教我的了 , 网上看了一发,犯这个错误的人还是不少的。
先抛出结论:这个单例写法不是线程安全的。
测试中发现的问题, 于是要验证分析一波, 编译器到底是怎么处理这个写法的才导致了这个写法的非线程安全的结果, 做如下测试代码:
直接VS中运行起来,在断点处断下, 右键 - 转入反汇编模式,得如下编译器实现代码:
参看上面的几句注释代码发现, 编译器在静态变量的地址紧挨着的四字节位置设置了一个保护标志位,内存布局如下:
所以,多线程问题的引入就是这个标志位没有任何保护,所以导致 this 指针的这个位置也没有了保护,因此引入了 getInstance 的多线程问题