简介

List接口在java.util.concurrent包下只有CopyOnWriteArrayList一个实现类,它是一个线程安全的数据结构。

实现

CopyOnWrite(写时拷贝)是为了并发而实现的一种懒惰策略。通常我们为了实现并发都是使用锁来实现的,比如使用synchronized关键之等。但是锁会带来性能上的开销。为了提高性能,CopyOnWrite采用的是一种读写分离的思想,其原理如下:

当需要修改目标数据时,先将目标数据复制一份,并在这份复制的数据上进行修改(此时如果有其他线程来读取数据则正常的从原数据上读取),修改完成后再将数据的引用指向这份复制出来并修改后的数据。这样就在不用锁的条件下实现了对数据的并发读写。

CopyOnWrite的特点就是:在同一时刻,可以有多个线程进行读操作,但是只能有一个线程进行写操作。

如果明白了CopyOnWrite机制,那么CopyOnWriteArrayList就很简单了。

我们先来看下读操作源码:

public E get(int index) {

return get(getArray(), index);

}

final Object[] getArray() {

// 获取当前数组

return elements;

}

private E get(Object[] a, int index) {

// 从给定的数组中取index位置的元素

return (E) a[index];

}

读操作的源码很简单,没有任何加锁机制。

我们再来看看写操作源码:

public boolean add(E e) {

// 因为写操作只能同时有一个线程进行,所以这里加了锁

// 这里用的是一个Object(lock)对象来作为锁的,所以不会影响读操作

synchronized (lock) {

// 获取当前数组

Object[] elements = getArray();

int len = elements.length;

// 对当前数组进行复制

Object[] newElements = Arrays.copyOf(elements, len + 1);

// 修改复制出来的数组

newElements[len] = e;

// 将数组引用重新指向这个修改后的数组

setArray(newElements);

return true;

}

}

final void setArray(Object[] a) {

elements = a;

}

可见,写操作也是非常简单的,因为同一时刻只能有一个线程进行写操作,所以这里使用了synchronized来进行同步。

总结

CopyOnWriteArrayList使用CopyOnWrite机制来实现了同步,比用锁性能更高。它也是采用了空间换时间的思想。但是,CopyOnWriteArrayList也有两个缺点:

内存问题,在写操作时因为要对数组进行复制,此刻内存中就会存在两份数据,这样会导致写的时候内存占用比较高,数据越多越明显;

数据一致性问题,不能保证数据的实时一致性,比如在读的时候并不能保证能读取到最新数据,它只能保证数据的最终一致性。

java list 数据分离_Java(Android)数据结构汇总(一)-- List(下)相关推荐

  1. java 对象向上转型_JAVA对象向上转型和向下转型

    今天做了一个测试的题目,发现自己还是很多问题没有静下心来做.很多问题是可以自己解决的但是自己一是没有读清题意,二是自己心里太急躁了.所以这个要自己应以为鉴! 对象的转型问题其实并不复杂,我们记住一句话 ...

  2. java数据结构图_java总结数据结构和算法

    数据结构分类:线性结构和非线性结构 线性结构包括:数组,链表,队列,栈: 非线性结构包括:树,图,表: 数组是查询快,插入和删除慢,因为需要对元素移动空间 链表是元素可以不连续内存中,是以索引将数据联 ...

  3. java 的数据类型转换_java数据类型转换汇总

    Java的数据类型的转换一般分为三种,分别是:简单数据类型之间的转换.字符串与其他数据类型的转换.其他实用数据类型的转换. 一.简单数据类型之间的转换 在java中,整型.实型.字符型被视为简单数据类 ...

  4. java tcp数据包_java tcp封装成数据包【相关词_ tcp数据包处理java】

    2-1.数据序号32位,TCP为发送的每一个字节都编一个号码,这里存储当前数据包数据第一 包括 网络编程结构数据JavaTCPIP的信息,所有JAVA网络编程:TCP/IP数据包结构相关内 Java实 ...

  5. java电台数据解析_Java数据解析---SAX

    一.Sax解析 是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档. Sax采用事件驱动的方式解析文档.简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回 ...

  6. java虚成员函数_Java常见知识点汇总(④)——虚函数、抽象函数、抽象类、接口...

    一. Java虚函数 虚函数的存在是为了多态. 它虚就虚在所谓"推迟联编"或者"动态联编"上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的. ...

  7. java xml数据解析_java xml解析,数据读取

    xml格式<?xmlversion ="1.0"encoding="UTF-8"?> xml格式 32 寺坡镇管理员 202cb962ac59075 ...

  8. java manager 如何使用_java - Android:如何使用AlarmManager

    android示例代码中有一些很好的例子 \ Android的SDK\样品\机器人-10\ ApiDemos\ SRC \ COM\示例\机器人\的API\应用 要检查的是: AlarmControl ...

  9. java oracle数据备份_Java后台备份oracle数据库脚本

    package atest; import java.io.BufferedReader; import java.io.File; import java.io.IOException; impor ...

最新文章

  1. 你真的会用Android的Dialog吗?由一个Exception想到的
  2. 【 NLS 】Steepest Descent Algorithm Iteration Procedure of TOA - Based Positioning
  3. 碎片化趋势下手机浏览器或成赢家
  4. 51nod1743-雪之国度【最小生成树,LCA,并查集】
  5. php强制cookies,php Cookies操作类(附源码)
  6. 今天写了一个含配置文件的 文件分割 及 合并 的java程序。
  7. red hat linux 虚拟机,Red Hat linux 的安装详细流程(包括VM虚拟机的设置)
  8. python 数据结构面试_【Python排序面试题】面试问题:所谓数据结构,… - 看准网...
  9. 使用 HTML、CSS 和 JS 制作一个中国象棋
  10. 单片机应用系统设计技术——多功能出租车计费器
  11. 写出ch为英语字母的c语言表达式,变量英文,编程 变量 定义的英语
  12. 配置微软Azure Kinect DK 录制器k4arecorder
  13. R绘图笔记 | 生存曲线的绘制
  14. 通过uc_client接口方式,更新discuz会员头像
  15. win10 RTX30系列显卡 安装tensorflow-gpu 1.15
  16. TalkingData:未来10年是大数据价值变现的阶段
  17. 人工智能及其应用——第一章学习笔记
  18. HTML如何实现带有滚动条的文本框
  19. 可视化界面:Activity 详解
  20. 不用库函数实现计算tan函数

热门文章

  1. SAP License:SAP顾问是如何炼成的——我所理解的SAP顾问
  2. 中小微企业公共信用数据的风险评估
  3. 用户数据销售额分析动态大屏看板+大屏数据可视化图表组件(折线图+圆柱图+散点图+饼图+漏斗图+雷达图+水位图)+智能web端高保真大数据动态可视化大屏看板+中国动态地图+智慧电商实时动态数据大屏看板
  4. 图书管理系统(微信、后台、网页端)总结
  5. python :编写装饰器
  6. get请求和post请求乱码问题
  7. Javabean的理解(通过javabean的部分程序)
  8. 学习笔记 - Nginx在多层代理下获取真实客户端IP地址
  9. 生活杂记 - 丢东西
  10. Android 中文件类型与MIME的匹配表