Java并发编程原理与实战三十四:并发容器CopyOnWriteArrayList原理与使用
1、ArrayList的实现原理是怎样的呢?
顾名思义,当数组有变化时重新建立一个新的数组。其设计是对于线程安全容器Vector使用中出现问题的一种解.
在Vector容器中,当需要执行复合操作
代码1
class Observable
{
private List<Observer> observers=new Vector<Observer>(); public void addObserver(){...}
public void removeObserver(){...}
public void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}
Observable中的notify方法在单线程中的实现是正常的,但在多线程中,由于在notify执行过程中observers数组的内容可能会发生改变,导致遍历失效.即使observers本身是线程安全的也于是无补
通常解决这个问题,可以使用同步方法或者加锁
代码2
class Observable
{
private List<Observer> observers=new Vector<Observer>(); public synchronized void addObserver(){...} public synchronized void removeObserver(){...} //同步方法
public synchronized void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}
这样的解决方案中notify的同步导致另外一个问题,即活跃性问题.当observers中有很多元素或者每一个元素的notify方法调用需要很久时,此方法将长时间持有锁.导致其他任何想修改observers的行为阻塞.最后严重影响程序性能
CopyOnWriteArrayList即在这种场景下使用.一个需要在多线程中操作,并且频繁遍历.
其解决了由于长时间锁定整个数组导致的性能问题.
其解决方案即写时拷贝。
我们先来贴出使用CopyOnWriteArrayList的Observable代码
代码3
class Observable
{
private List<Observer> observers=new CopyOnWriteArrayList<Observer>(); public void addObserver(){...} public void removeObserver(){...} public void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}
Observable的notify方法和代码1相同.但其不会有多线程同时操作的问题.其中的奥秘,通过分析源码可知
当CopyOnWriteArrayList添加或者删除元素时,其实现为根据当前数组重新建立一个新数组..
Java并发编程原理与实战三十四:并发容器CopyOnWriteArrayList原理与使用的更多相关文章
- Java并发编程原理与实战三十五:并发容器ConcurrentLinkedQueue原理与使用
一.简介 一个基于链接节点的无界线程安全队列.此队列按照 FIFO(先进先出)原则对元素进行排序.队列的头部 是队列中时间最长的元素.队列的尾部 是队列中时间最短的元素.新的元素插入到队列的尾部,队列 ...
- Java并发编程原理与实战三十二:ForkJoin框架详解
1.Fork/Join框架有什么用呢? ------->Fork使用来切分任务,Join是用来汇总结果.举个简单的栗子:任务是1+2+3+...+100这个任务(当然这个任务的结果有好的算法去做 ...
- Java并发编程原理与实战二十四:简易数据库连接池
public class MyDataSource { private static LinkedList<Connection> pool = new LinkedList<> ...
- Java并发编程原理与实战三十六:阻塞队列&消息队列
一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...
- Java并发编程原理与实战三十八:多线程调度器(ScheduledThreadPoolExecutor)
在前面介绍了java的多线程的基本原理信息:线程池的原理与使用 本文对这个java本身的线程池的调度器做一个简单扩展,如果还没读过上一篇文章,建议读一下,因为这是调度器的核心组件部分. 我们如果要用j ...
- Java并发编程原理与实战三十:CountDownLatch与CyclicBarrier 区别
相信每个想深入了解多线程开发的Java开发者都会遇到CountDownLatch和CyclicBarrier,大家也在网上看到各种介绍原理,代码的,以及他们区别(应付面试)的,但是很少能讲清楚:他们到 ...
- Java并发编程原理与实战三十九:JDK8新增锁StampedLock详解
1.StampedLock是做什么的? ----->它是ReentrantReadWriteLock 的增强版,是为了解决ReentrantReadWriteLock的一些不足. 2.Ree ...
- Java并发编程原理与实战三十七:线程池的原理与使用
一.简介 线程池在我们的高并发环境下,实际应用是非常多的!!适用频率非常高! 有过使用过Executors框架的朋友,可能不太知道底层的实现,这里就是讲Executors是由ThreadPoolExe ...
- 《Java多线程编程核心技术》读后感(十四)
单例模式与多线程 立即加载/饿汉模式 立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接new实例化. 立即加载/饿汉模式实在调用方法前,实例已经被创建了 package Six; p ...
随机推荐
- 团队作业4 Alpha冲刺《嗨!你的快递》
仓库地址:https://git.coding.net/day_light/ourexpressmaster1.git 张新宇 1第一天日期:2018/6/13 1.1今日任务 进行核心功能数据匹 ...
- 四则运算web版
1)在文章开头给出Coding.Net项目地址.(1') https://git.coding.net/meiyoupiqidefan/jieduizuoye.git url测试地址:http://3 ...
- 第一个spring冲刺心得及感想
在这次spring中,学到了不少东西: 1.团队协作精神 2.任务细节化,任务燃尽图 3.身为sm的责任 但是在过程中也认识到了一些不足 1.对于团队协作完成一个大的项目还是不熟悉 2.个人能力的不足 ...
- python基础(三)python数据类型
一.数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需 ...
- Nginx负载均衡配置与负载策略
原理 负载均衡的目的是为了解决单个节点压力过大,造成Web服务响应过慢,严重的情况下导致服务瘫痪,无法正常提供服务. 应用场景 春节期间在12306网站上买过火车票的朋友应该深有体会,有时查询一张火车 ...
- bzoj2095-Bridge
题意 一个 \(n\) 个点 \(m\) 条边的图,每条边双向都有权值(可能不一样).求从 1 开始,经过所有点,经过所有边一次且仅一次(即一定要经过这条边的某个方向)回到 1 的路径上权值最大的最小 ...
- Python语言算法的时间复杂度和空间复杂度
算法复杂度分为时间复杂度和空间复杂度. 其作用: 时间复杂度是指执行算法所需要的计算工作量: 而空间复杂度是指执行这个算法所需要的内存空间. (算法的复杂性体现在运行该算法时的计算机所需资源的多少上, ...
- oracle 空表导出dmp会报错
步骤一.查找出来的语句全部复制并执行 select 'analyze table '||table_name||' compute statistics;' from user_tables; 步骤二 ...
- plsql 只有三个文本框,无法登陆
plsql版本与oracle版本不一致,如 你装的是oracle 64位,但是plsql装的是32位,就会出问题了,解决方案就是下载个64位plsql
- 什么是 metadata (元数据)
1. 什么是元数据 任何文件系统中的数据分为数据和元数据.数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限.文件拥有者以及文件数据块的分布信息(inode...) ...