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 ...
随机推荐
- Android-TCP编程
以下是PC端代码: package com.example.sxb.myapplication;import java.io.BufferedReader;import java.io.IOExcep ...
- 如何解决abd.exe已停止工作
打开电脑,右键点击属性会出现如下界面: 点击左边高级系统设置:将会出现如下界面: 点击环境变量,点编辑. 把环境变量中的 ANDROID_ADB_SERVER_PORT 改成1122以后还遇到这个问 ...
- BETA-2
前言 我们居然又冲刺了·二 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 过去两天完成了哪些任务 了解OpenCV下的视频参数及其调用方法 初步编码 接下来的计划 文档工作 速 ...
- 重学 以太网的mac协议的CSMA/CD
之前上课一直模糊的CSMA/CD进行系统性整理. CSMA/CD (Carrier Sense Multiple Acess/Collision Detect)应用在OSI的 数据链路层 在以太网中, ...
- 项目报错“JavaServer Faces 2.2 can not be installed : One or more constraints”等一系列问题
在做springmvc+maven项目时,经常遇到如下错误: 解决办法(这里以jdk1.8,web3.0为例): 一:保证build path的jre版本 remove掉旧版本的,add新版本 二:保 ...
- Keil MDK中的Code, RO-data , RW-data, ZI-data分别代表什么意思?(转)
一 基础知识 字节 8位半字 16位字 32位 二 解惑 Code, RO-data,RW-data,ZI-data Code为程序代码部分RO-data 表示 程序定义的常量const t ...
- sitemesh入门
今天在公司用到了sitemesh这个框架. 网上的资料已经有很多了. 在此就不做具体介绍了, 仅仅做个笔记. sitemesh是一种模板框架,是为了解决页面重复代码而设计的. 设计思想 siteme ...
- 【Leetcode】86. Partition List
Question: Given a linked list and a value x, partition it such that all nodes less than x come befor ...
- PAT 甲级 1154 Vertex Coloring
https://pintia.cn/problem-sets/994805342720868352/problems/1071785301894295552 A proper vertex color ...
- 解决:"2013-01-06 00:00:00" is not a valid date and time.
在转换时间格式时,遇到以下问题: 弹出对话框:"2013-01-06 00:00:00" is not a valid date and time. 在百度上查找,发现是本地日期格 ...