ArrayList不是线程安全的链表。
线程安全的意思就是多个线程访问相同数据时,无论怎么访问,数据的状态都要保持一致(和一个线程单独访问的结果是一样的)。
比如说,有两个线程,一个线程对同一个整数变量自增运算100次,另一个线程对同一个整数变量自减50次,如果算法是线程安全的,那么,两个线程同时运行之后,结果和单独一个线程先自增100次再自减50次是一样的。这就要求,每一次的自增(自减)操作,都是线程安全的才可以。
楼主可能不太理解,为啥两个线程同时访问同一个内存变量会出现差错。这是由于线程切换和多CPU的缓存造成的。一般都解释为线程切换造成的。
这是一个比较讲究细节的过程,一个线程运行的时候,同一时间另一个线程可能没有处于运行状态。操作系统中有两三千个线程需要运行,CPU核心数也就那么几个,所以要轮着来使用。线程切换的时候,需要先将要换出去的线程进行现场保护,将当时的线程状态保存起来,包括CPU寄存器中的数据,会被压入线程栈中,之后再将切换进来的线程进行现场还原,从线程栈中把CPU寄存器的数据还原回去。我们知道,CPU做的算术运算和逻辑运算都是在寄存器之间做的,做完之后再回写到内存中。这样的话,寄存器的数据相当于内存数据的一个镜像。多个线程访问同一个内存数据,就会有多个镜像,那么,在线程切换的时候,镜像没来得及回写到内存就被压栈了,其他线程更改镜像有的就可以及时回写,等刚才那个没来得及回写的线程被恢复运行时,第一件事就是回写他上一次执行的镜像,那么,其他线程的镜像被覆盖掉了,最终造成了内存数据的不一致。
多CPU时,由于每块CPU都自带缓存cache,也会造成这种现象。
我之所以写这些,就是因为,楼主在表述问题时,把程序正在操纵的数据与链表混为一谈,细节上,两者是截然不同的东西,虽然,你的代码操纵的就是链表,但是,实际上,操纵的是链表里面的东西(内容结构)。链表被覆盖指的是链表的引用被其他东西覆盖了,和链表内部,指向链表元素的引用被其他东西所覆盖,是两个概念。而且,不单单是引用,链表的大小也会产生线程安全的问题,所以,整个链表就不是线程安全的