公开课总结与感悟:并发容器CopyOnWriteArrayList的学习以及延伸

昨天晚上在云析学院听了一堂公开课,感觉受益匪浅呀,特地作此总结。
首先老师通过在多线程情况下验证数组 ArrayList 不是线程安全的,由此引申出线程安全的数组 CopyOnWriteArrayList 。
下面我们先来看一下什么是线程安全,什么是线程不安全,并分析一下多线程情况下 ArrayList 线程不安全的原因
1.什么是线程安全?

权威答案:线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,
		线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
通俗的讲:多线程情况下存在的共享资源,在被一个线程得到以后,资源会被上锁,期间其他线程不能再访问该资源,
		必须等到使用这个资源的线程结束并且解锁之后才能再去访问,以此来保证共享资源的正确性与一致性。
最简单的理解就是:多线程情况下共享数据能够保持一致。

2.什么是线程不安全?

知道了线程安全那线程不安全就好说了,说最好懂的:线程不安全就是指在多线程情况下数据可能会出现不数据不一致或者数据污染的情况。

3.ArrayList线程不安全的原因:是因为 ArrayList 对于读,写等操作都没有做加锁(也就是不能保证线程同步),所以多线程情况下如果有多个线程同时对ArrayList进行写操作时,就会出现问题,例如数组越界,添加的值为null等等。

至于为什么会出现这些错误,各位小伙伴可以去看看这篇文章,写的很不错:为什么说ArrayList是线程不安全的?

了解了上面这些问题下面我们就看看能够保证线程安全的CopyOnWriteArrayList吧。
 首先讲CopyOnWrite容器,CopyOnWrite容器即写时复制的容器(也叫作并发容器)。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行复制,得到一个新的容器,然后往新的容器里面添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写的容器不是同一个。

这样做的话就能够保证线程每次读的数据都会是一致的,而且也无需加锁,优化了性能。
但是需要的代价就是需要更大的空间了,每次写的时候都需要复制原来的容器,用的是空间换时间;所以我们使用CopyOnWriteArrayList的情况应该是读多写少的场景;不利于写多的场景,因为写的时候CopyOnWriteArrayList是需要加锁的,对性能的损耗太大。并且对于数据的一致性要求不是非常高,因为CopyOnWriteArrayList保证的是数据的最终一致性,并不能完全保证数据的实时一致性。它的优点很多,但是也是有不适合的场景,这是不可避免的。

讲解完CopyOnWriteArrayList之后,由于上面讲到了锁机制,这时老师又提出了很多锁的概念(重入锁,公平锁,偏向锁,轻量级、重量级锁等等);想要了解java里面各种锁的机制与特性可以去看这篇博客: java中锁的分类 写的很好哟

而且CopyOnWriteArrayList用到了读写分离的原理,这又可以结合到数据库的读写分离,它的重入锁机制又可以引出synchoronized,volatile等java常见用来做线程同步的关键字。下面我要说的就是java中volatile关键字。

在听课的时候老师也问到了我们关于volatile关键字的作用,能回答的上看来的人并不多;
下面我们说说volatile关键字作用吧:
1.禁止指令重排序
2.保证内存的可见性

首先来解释一下这两个作用

  1. 我们知道在程序执行时,为了提高性能,编译器和处理器都可能会对我们的指令进行重新排序;但是很多时候我们的代码如果重新排序的话很可能就会导致代码异常甚至报错,而volatile关键字就能够保证不会发生这种情况。
  2. 保证内存可见性就是指:对于共享的资源,所有线程看到的都是最新的数据;也就是是volatile能够保证数据的强一致性;
    这里提一下的是,volatile并不能保证绝对的原子性;

下一步我们就要知道如何使用volatile变量,这里引用一片大牛的博客,因为我认为自己了解的不够深入,这篇文章写得很好

正确使用 Volatile 变量

最后总结一下:其实很多时候我们在面试时一个很小的点往往能够被延伸到很多的知识面,所以我们学习一定不能过于片面,这是云析学院这堂课程给我最大的感受,加油!各位小伙伴。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱与心光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值