本文从代码审查过程中发现的一个ArrayList相关的「线程安全」问题出发,来剖析和理解线程安全。
案例分析
前两天在代码Review的过程中,看到有小伙伴用了类似以下的写法:
ListStringresultList=newArrayList();paramList.parallelStream().forEach(v-{Stringvalue=doSomething(v);resultList.add(value);});印象中ArrayList是线程不安全的,而这里会多线程改写同一个ArrayList对象,感觉这样的写法会有问题,于是看了下ArrayList的实现来确认问题,同时复习下相关知识。
先贴个概念:
线程安全是程式设计中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。——维基百科
我们来看下ArrayList源码里与本话题相关的关键信息:
publicclassArrayListEextendsAbstractListEimplementsListE,RandomAccess,Cloneable,java.io.Serializable{//.../***ThearraybufferintowhichtheelementsoftheArrayListarestored.*ThecapacityoftheArrayLististhelengthofthisarraybuffer...*/transientObject[]elementData;//non-privatetosimplifynestedclassaccess/***ThesizeoftheArrayList(thenumberofelementsitcontains).*/privateintsize;//.../***Appendsthespecifiedelementtotheendofthislist...*/publicbooleanadd(Ee){ensureCapacityInternal(size+1);//IncrementsmodCount!!elementData[size++]=e;returntrue;}//...}从中我们可以