除了加锁外,其实还有一种方式可以防止并发修改异常,这就是将读写分离技术(不是数据库上的)。

先回顾一下一个常识:

1、JAVA中“=”操作只是将引用和某个对象关联,假如同时有一个线程将引用指向另外一个对象,一个线程获取这个引用指向的对象,那么他们之间不会发生ConcurrentModificationException,他们是在虚拟机层面阻塞的,而且速度非常快,几乎不需要CPU时间。

2、JAVA中两个不同的引用指向同一个对象,当第一个引用指向另外一个对象时,第二个引用还将保持原来的对象。

基于上面这个常识,我们再来探讨下面这个问题:

在CopyOnWriteArrayList里处理写操作(包括add、remove、set等)是先将原始的数据通过JDK1.6的Arrays.copyof()来生成一份新的数组

然后在新的数据对象上进行写,写完后再将原来的引用指向到当前这个数据对象(这里应用了常识1),这样保证了每次写都是在新的对象上(因为要保证写的一致性,这里要对各种写操作要加一把锁,JDK1.6在这里用了重入锁),

然后读的时候就是在引用的当前对象上进行读(包括get,iterator等),不存在加锁和阻塞,针对iterator使用了一个叫COWIterator的阉割版迭代器,因为不支持写操作,当获取CopyOnWriteArrayList的迭代器时,是将迭代器里的数据引用指向当前引用指向的数据对象,无论未来发生什么写操作,都不会再更改迭代器里的数据对象引用,所以迭代器也很安全(这里应用了常识2)。

CopyOnWriteArrayList中写操作需要大面积复制数组,所以性能肯定很差,但是读操作因为操作的对象和写操作不是同一个对象,读之间也不需要加锁,读和写之间的同步处理只是在写完后通过一个简单的“=”将引用指向新的数组对象上来,这个几乎不需要时间,这样读操作就很快很安全,适合在多线程里使用,绝对不会发生ConcurrentModificationException,所以最后得出结论:CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。

读CopyOnWriteArrayList有感的更多相关文章

  1. 新生 & 语不惊人死不休 —— 《无限恐怖》读后有感

    开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...

  2. <<编程之美>>1.2读后有感

    问题提出 中国象棋的"将","帅"问题,他俩不能在一条直线上.求出他们的合法位置,并且只能用一个变量. 分析 一头雾水,不明所以.往下看了下,感觉像是程序员为难 ...

  3. 读redux有感: redux原来是这样操作的。

    2017.9.10日 教师节 : ~当一个事物你没有接触,但是生活中 常常用到他,你就不得不去了解他了. 注:新手可以看一下,毕竟博主也是个菜鸟,没法写高深的东西,不想看博主扯淡的直接看第三节啦~~ ...

  4. 先有 Mac 还是先有银元?

    自从开设了这个公众号以后,收到最多的问题是:听了 Mac 君的介绍,我也觉得 Mac 很好,可是穷屌丝一枚,真买不起,怎么破?前几天我在微博上说,读了我的书,就有 Mac 了.居然有读者来问:这是真的 ...

  5. 关于退运美国转基因玉米含有MRI 162转基因成分的质疑

    6月30日,新华社刊出文章"我国退运125.2万吨进口美国转基因玉米",读后有感. 文章说:国家质检总局办公厅副主任陆春明30日介绍,截至今年6月16日,全国出入境检验检疫机构共在 ...

  6. XP用户:消除误解,大胆拥抱Linux

         4月23日.知名家评论家Silviu Stahie发表文章.题为"Windows Users and Their Misconceptions About Linux". ...

  7. 集大1513 & 1514班 软件工程第一次作业评分与点评

    谢谢大多数同学按时完成了作业,同学态度都比较端正,没有为了完成作业或者讨好老师而说一些假话空话. 很多同学选择CS之前并没有从兴趣或者擅长出发.这是一个普遍的现象,十年前我们是这样,十年后的孩子们还是 ...

  8. [ZZ] [精彩盘点] TesterHome 社区 2018年 度精华帖

    原文地址: https://testerhome.com/topics/17646 相逢即是缘分,总有一篇适合您! 感觉好的请点赞收藏 ,感觉分类不严谨的,欢迎反馈给我! 测试方法&测试管理 ...

  9. 20155303 2016-2017-2 《Java程序设计》课程总结

    20155303 2016-2017-2 <Java程序设计>课程总结 目录 一.每周作业及实验报告链接汇总 二.关于博客 自认为写得最好一篇博客是?为什么? 作业中阅读量最高的一篇博客是 ...

随机推荐

  1. vuex是啥

    vuex是一个状态管理工具. vuex store与一个简单的全局变量的区别是: 1.vuex stores 是响应式的,当组件改变state时,它能响应并高效地更新state. 2.state不能被 ...

  2. 终于解决了IE8不支持数组的indexOf方法,array的IndexOf方法

    /* 终于解决了IE8不支持数组的indexOf方法 */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (el ...

  3. 向下滚动页面加载图片的js

    js代码 scroll.photo.js : window.imgscroll = { options: { target: null, //插入图片的目标位置 img_list: null, //图 ...

  4. 请尝试使用 Console.Read。错误原因

    当出现错误: 如果应用程序没有控制台或控制台输入已通过文件进行了重定向,则无法读取键.请尝试使用 Console.Read. 一定是在非控制台应用程序中用了Console.ReadKey(); Con ...

  5. IIs配置文件存放路径

    IIS 5 中,IIS的配置文件在: C:\WINNT\system32\inetsrv\MetaBase.bin IIS 6 中,IIS 的配置文件在: C:\WINDOWS\system32\in ...

  6. iOS开发UI篇—APP主流UI框架结构

    iOS开发UI篇—APP主流UI框架结构 一.简单示例 说明:使用APP主流UI框架结构完成简单的界面搭建 搭建页面效果:                                二.搭建过程和 ...

  7. NGINX location 在配置中的优先级

    location表达式类型 ~ 表示执行一个正则匹配,区分大小写 ~* 表示执行一个正则匹配,不区分大小写 ^~ 表示普通字符匹配.使用前缀匹配.如果匹配成功,则不再匹配其他location. = 进 ...

  8. 【BZOJ】2719 银河之星

    可以将棋子分为9种类型.且可以通过合并使得两个不同种类棋子转换为另一种棋子(不过要注意棋盘大小,有的时候硬要合并会到棋盘外面,可以先把棋盘全部转换,然后枚举每一个棋子的转换).然后把状态压成一个十位的 ...

  9. 1、android源代码下载及目录分析,和eclipser的跟踪

    1.在eclipse中跟踪源代码:假如对mainactivity.java里面的activity按Ctrl+鼠标左键(前提已经导入android源代码:方法1:在项目点击右键,然后找到properti ...

  10. 从c开始,小小感悟

    c语言是众多编程小白进入编程大门的钥匙,不过许多人在学习一段时间以后就渐渐产生了困惑,枯燥的黑色界面渐渐让他们失去了"渴望",---我还不能制作出一款像样的软件,我还是只是在算数学 ...