您当前的位置: 首页 >  ar

wu@55555

暂无认证

  • 3浏览

    0关注

    201博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

CopyOnWriteArrayList的迭代器支持fast-fail吗 Concurrent包的迭代器支持fast-fail吗

wu@55555 发布时间:2021-07-01 01:39:20 ,浏览量:3

如果你了解这个集合,且清楚写时复制原理,可以直接跳到最后查看答案

什么是CopyOnWriteArrayList

容器分为两大类:Collection和Map 就Map而言,其HashMap在多线程高并发场景下有ConcurrentHashMap来保障线程安全

那么JUC包下有支持list线程安全的容器吗?

首先呢Vector是线程安全的,但它的做法是直接在方法上加synchronized,这导致效率不高。 我们有很多场景是读多写少,写的时候可以加锁保证数据一致性,但是读的时候是没有必要加锁的。 因此CopyOnWriteArrayList和CopyOnWriteArraySet就产生了

它的读写锁的概念和ReentrantReadAndWriteLock的读写锁概念类似,即是读共享锁,写排他锁。但是CopyOnWriteArrayList更进一步的是,它连读都不加锁,并且一边写还能一边读,也就是说写不会阻塞读。这是怎么做到的呢?就要谈到CopyOnWrite写时复制机制,这个机制本身在linux系统底层和其他很多地方都有应用,比如redis的rdb持久化空间时fork子进程就用到了这个机制。

具体是直接把写入的数组拷贝一份,修改操作是在拷贝的副本中进行的,因此在原来对象上的读就不受影响。写完后再指向副本,这样原来的数组就会被GC回收了。并且CopyOnWriteArrayList在写入时的加锁是通过ReentrantLock实现的,即底层是CAS操作,性能上得到了提升。当然在jdk1.8之后synchronized的性能也得到了改善,并不比ReentrantLock差多少,而且官方也更加推荐使用synchronized

什么是fast-fail呢?

即快速失败机制,是java集合中的一种错误检测机制。当使用迭代器Iterator迭代集合的过程中该集合在结构上发生变化时就有可能发生fail-fast,抛出ConcurrentModificationException异常,在不同步的修改并不一定会抛,只是尽量抛出异常

什么叫集合的结构发生变化?就是元素多了或者少了,如果只是修改了元素值结构并没有发生变化

List,HashMap迭代器都支持fast-fail,即迭代器迭代时容器结构发生变化都会抛出ConcurrentModificationException

CopyOnWriteArrayList的迭代器支持fast-fail吗?

不支持! 因为写时复制的存在,CopyOnWriteArrayList在使用迭代器迭代的时候,实际上迭代的是原数组,而不是更新的数组,所以中间如果发生新增、删除元素是在新数组上发生的,所以不影响旧数组的迭代,但是正因为元素的迭代发生在旧数组上,所以迭代时更新的数据是获取不到最新的,存在时延。

测试:

@Test
    public void test3(){
        CopyOnWriteArrayList list = new CopyOnWriteArrayList();
        for (int i = 0; i             
关注
打赏
1664985904
查看更多评论
0.0405s