五.线程安全版的ArrayList
CopyOnWriteArrayList是什么?我们看一下源码注释上面是怎么说的:
相对于ArrayList而言,CopyOnWriteArrayList集合是线程安全的容器。在遍历的时候,由于它操作是数组的"快照","快照"不会发生变化。所以它不需要额外加锁,也不会抛出ConcurrentModificationException异常。
我们主要看一下,示例程序中用到的三个方法,add(E e)、next()、remove(Obj)
先看add(E e)方法:
但是当我阅读源码,从add方法可以看出CopyOnWriteArrayList并不保证数据的实时一致性。只能保证最终一致性。
同时我们从源码中可以看出CopyOnWriteArrayList增删改数据的时候需要搞一个"快照",这一点是比较耗内存的,使用过程中需要注意。
六.总结一下
我们再回到最开始的地方,看看大家的回答:
1.什么也不会发生,remove之后,list中的数据会被清空。
2.remove的方法调用错误,入参应该是index(数组下标)。
3.并发操作的时候会出现异常。
4.会发生ConcurrentModifyException。
现在,你知道这些回答的问题在哪里了吧?这一部分的总结也很简单,上一个对比图就好了,如果看不清楚,你可以点开看大图:
七.回答另外一个面试题
现在面试官经常问的一个问题,你读过源码吗?
咦,巧了。你看了这篇文章,就相当于了读了ArrayList和CopyOnWriteArrayList的部分源码。
那你就可以这样回答啦:我之前看阿里Java开发手册的时候看到一条规则是
不要在foreach循环里面进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
我对这条规则很感兴趣,所以我对其进行了深入的研究,阅读了
ArrayList和CopyOnWriteArrayList的部分源码。
如果碰巧面试官也读过这块源码,这个问题,你们可以相谈甚欢。
如果面试官没有读过这块源码,你可以给他讲的明明白白。
当然,还有一个前提是:我希望你读完这篇文章后,如果是第一次知道这个知识点,那你可以自己实际操作一下。
看懂了是一回事,自己再实际操作一下,是另外一回事。
八.扩展阅读
8.1 fail-fast和safe-fast机制
文中多次提到了"fail-fast"机制(快速失败),与其对应的还有"safe-fast"机制(失败安全)。
这种机制是一种思想,它不仅仅是体现在Java的集合中。在我们常用的rpc框架Dubbo中,在集群容错时也有相关的实现。
Dubbo 主要提供了这样几种容错方式:
Failover Cluster - 失败自动切换
Failfast Cluster - 快速失败
Failsafe Cluster - 失败安全
Failback Cluster - 失败自动恢复
Forking Cluster - 并行调用多个服务提供者
如果对这两种机制感兴趣的朋友可以查阅相关资料,进行了解。如果想要了解Dubbo的集群容错机制,可以看官方文档,地址如下:
http://dubbo.apache.org/zh-cn/docs/source_code_guide/cluster.html
8.2 Java语法糖
文中说到foreach循环的时候提到了Java的语法糖。如果对这一块有兴趣的读者,可以在网上查阅相关资料,也可以看看《深入理解Java虚拟机》的第10.3节,有专门的介绍。
书中说到:
总而言之,语法糖可以看做是编译器实现的一些“小把戏”,这些“小把戏”可能会使得效率“大提升”,但我们也应该去了解这些“小把戏”背后的真实世界,那样才能利用好它们,而不是被它们所迷惑。
8.3 阿里Java开发手册
阿里的孤尽大佬作为主要作者写的这本《阿里Java开发手册》,可以说是呕心沥血推出的业界权威,非常值得阅读。读完此书,你不仅能够获得很多干货,甚至你还能读出一点技术情怀在里面。
对于技术情怀,孤尽大佬是这样的说的:
热爱、思考、卓越。热爱是一种源动力,而思考是一个过程,而卓越是一个结果。如果给这三个词加一个定语,使技术情怀更加立体、清晰地被解读,那就是奉献式的热爱,主动式的思考,极致式的卓越。
关注公众号并回复关键字【Java】。即可获得此书的电子版。
九.最后说一点
这篇文章写之前我一直在纠结,因为感觉这个知识点其实我已经掌握了,那我还有写的必要吗?我在写的这个过程中还能收获一些东西吗?
但是在写的过程中,我翻阅了大量的源码,虽然之前已经看过,但是没有这样一行一行仔细的去分析。之前只是一个大概的模糊的影像,现在具象化清晰了起来,在这个过程中,我还是学到了很多很多。
其实想到写什么内容并不难,难的是你对内容的把控。关于技术性的语言,我是反复推敲,查阅大量文章来进行证伪,总之慎言慎言再慎言,毕竟做技术,我认为是一件非常严谨的事情,我常常想象自己就是在故宫修文物的工匠,在工匠精神的认知上,目前我可能和他们还差的有点远,但是我时常以工匠精神要求自己。就像我之前表达的:对于技术文章(因为我偶尔也会荒腔走板的聊一聊生活,写一写书评,影评),我尽量保证周推,全力保证质量。
才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言给我指出来,我对其加以修改。
如果你觉得文章还不错,你的点赞、留言、转发、分享、赞赏就是对我最大的鼓励
以上。
谢谢您的阅读,感谢您的关注。公众号会是文章首发平台,关注可以第一时间看到原创文章哦。