Java迭代器中,应用乐观锁应对线程不安全问题(为什么普通迭代器遍历过程中不允许使用集合对象更新集合?)

以List接口的实现类ArrayList为例:

应用迭代器遍历如下,while代码块内部允许使用迭代器删除(普通迭代器不能add)集合元素,但是不能调用集合的删除方法

List<String> list = new ArrayList<>();

Iterator<String> it = list.iterator();
while(it.hasNext()){
     String str = it.next();

     it.remove();

     // !!!l  list.remove(it);
     System.out.println(str);
}

下面是ArrayList的关于Iterator的部分源码(JDK8)截图

当调用集合对象的iterator方法时,返回一个new Itr();(一个迭代器对象)

 

ArrayList的内部类Itr实现类Iterator接口

  • cursor           表示调用next方法时要返回的元素索引,初始化为0
  • lastRet          表示上一次返回的元素索引,因为一开始未遍历过所以初始化为-1
  • expectedModCount  表示预计的modCount值
  • modCount     表示集合对象被更新(插入或删除)的次数
  • Itr()     构造方法

 内部类的hasNext方法,size就是集合的大小

 

 内部类的next方法,先不看checkForComodification方法,代码块其他内容就是在做返回索引对应元素值的工作

 checkForComodification方法,在每次调用next方法遍历时判断:modCount与expectedModCount是否相等,如果不相等,就说明modCount在迭代器初始化后改变了(集合更新了),发生了线程不安全的问题,即抛出异常。

 这里用到了乐观锁的思想,即每次尝试遍历前,先判断集合是否更新

下面给出modCount在集合更新时的操作:

ArrayList继承了AbstractList,集合实例化时modCount为0

 

 

更新时:

 

 

 其他更新也都更新了modCount

而expectedModCount除了在迭代器实例化时赋过值,其他地方均没有改变 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值