线程安全,在java的多并发编程中是重要概念,意思是,多个线程同时操作一个对象,在各种不同情况下,都不会造成不同的后果。
一个经典问题,Vector到底是不是线程安全的?
很多人都会回答,是,vector是线程安全的。
诚然,不止是很多IT教材上是这么写的,就连JDK的作者写的注释也是这么说的。如下图(图为 JDK中Vector的源代码):注释中,红框标记的部分写着:如果你不需要线程安全的实现类,那就推荐你用ArrayList,而不是Vector。言外之意,就是说,Vector是线程安全的。
自己看了源码,发现,确实很多方法都有同步关键字synchronized,从而保证所有的对外接口都会以 Vector对象为锁,即,在vector内部,所有的方法都不会被多线程访问。
但是,单个方法的原子性(注:原子性,程序的原子性即不会被线程调度机制打断),并不能保证复合操作也具有原子性。
(你问 为什么复合操作不能保证原子性? 参见大神的帖子:https://blog.csdn.net/xdonx/article/details/9465489 ,我没太多时间研究细节,所以就只好剽窃大佬的结论了╮( ̄▽ ̄")╭)
所以,这个问题的正确回答应该是:
虽然源代码注释里面说这个是线程安全的,因为确实很多方法都加上了同步关键字synchronized,但是对于符合操作而言,只是同步方法并没有解决线程安全的问题。
要真正达成线程安全,还需要以vector对象为锁,来进行操作。
所以,如果是这样的话,那么用vector和ArrayList就没有区别了,所以,不推荐使用vector。
所以说,就算是JDK,也会有坑,毕竟坑坑更健康,有坑才能引导我们思考,毕竟做程序是理科工作,要有怀疑精神。
其实,具体为什么复合操作不具有原子性,我也没有太深究,可能要从Vector代码里面找根据,有空再探究。