`

List浅析

阅读更多

java.util.List是java集合框架的基础接口之一,使用频率非常高,如下主要从数据结构和应用场景做简单分析,仅供交流和参考。

 

1.Vector

Jdk遗留类,现在使用很少,但了解下最初jdk集合类的实现方法也是不错的。添加、删除方法如下所示,都是通过synchronized关键字保证线程安全性。

public synchronized void addElement(E obj) {
	modCount++;
	ensureCapacityHelper(elementCount + 1);
	elementData[elementCount++] = obj;
}

public synchronized boolean removeElement(Object obj) {
	modCount++;
	int i = indexOf(obj);
	if (i >= 0) {
	    removeElementAt(i);
	    return true;
	}
	return false;
}

 

2.ArrayList数据结构是数组,非线程安全。

/**
* The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
 private transient Object[] elementData;

 

3.LinkedList数据结构是双向循环链表,非线程安全。

实现了双端队列方法,添加元素时,可以添加到list的头部或尾部。

public void addFirst(E e) {
        addBefore(e, header.next);
}
public void addLast(E e) {
	addBefore(e, header);
}

addBefore(E e, Entry<E> entry)实现了将e添加到entry元素之前,addFirst(e)将元素添加到header之后,也就是list的头部。addLast(e)将e添加到header之前,因为LinkedList是循环链表,header之前就是List尾部。

 

4.CopyOnWriteArrayList

CopyOnWriteArrayList是java.util.ArrayList的一个线程安全的变体。适用于读远远大于写的场景。

 

1)CopyOnWriteArrayList实现了List接口。

 

2)CopyOnWriteArrayList包含了成员变量lock。通过lock,实现了对CopyOnWriteArrayList的互斥访问。

/** The lock protecting all mutators */
transientfinal ReentrantLock lock = new ReentrantLock();

 

 3)CopyOnWriteArrayList包含了成员array数组,这说明CopyOnWriteArrayList本质上通过数组实现的。 

CopyOnWrite的缺点

CopyOnWrite容器有很多优点,但是同时也存在两个问题,即内存占用问题和数据一致性问题。所以在开发的时候需要注意一下。内存占用可以从使用场景来规避,读多写少的场景比较适合选择CopyOnWriteArrayList。数据一致性问题是网上看到的一种错误分析,后面做了浅析。

 

内存占用

因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象(有两份对象内存,新数组生成后就使用新数组了,java代码中没有删除旧数组的操作,可能是依靠jvm GC来回收)。如果这些对象占用的内存比较大,比如说200M左右,那么再写入100M数据进去,内存就会占用300M,那么这个时候很有可能造成频繁的Yong GC和Full GC。

 

数据一致性 

从代码来看,通过ReentrantLock保证了线程的安全性,显示锁在内存可见性上和Synchronized是一致的,所以,不存在数据一致性的问题。

 

JDK 注释:

 

A thread-safe variant of java.util.ArrayList in which all mutativeoperations (add, set, and so on) are implemented bymaking a fresh copy of the underlying array.

This is ordinarily too costly, but may be more efficientthan alternatives when traversal operations vastly outnumbermutations, and is useful when you cannot or don't want tosynchronize traversals, yet need to preclude interference amongconcurrent threads.  The "snapshot" style iterator method uses areference to the state of the array at the point that the iteratorwas created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator isguaranteed not to throw ConcurrentModificationException.

The iterator will not reflect additions, removals, or changes tothe list since the iterator was created.  Element-changingoperations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.

All elements are permitted, including null.

 

0
2
分享到:
评论

相关推荐

    C#中数组、ArrayList、List、Dictionary的用法与区别浅析(存取数据)

     在工作中经常遇到C#数组、ArrayList、List、Dictionary存取数据,但是该选择哪种类型进行存储数据,对于初学者的我一直不知道该怎么取舍。于是抽空好好看了下他们的用法和比较,在这里总结下来,后面有需要改进的...

    MTK平台CAMERA驱动浅析

    5、 USER SPACE的SENSORLIST,向用户空间提供支持的SENSORLIST ......................... - 10 - 6、 SENSOR 效果调整的接口 .....................................................................................

    深入浅析Python中list的复制及深拷贝与浅拷贝

    主要介绍了Python中list的复制及深拷贝与浅拷贝及区别解析 ,需要的朋友可以参考下

    浅析C#中数组,ArrayList与List对象的区别

    在C#中,当我们想要存储一组对象的时候,就会想到用数组,ArrayList,List这三个对象了。那么这三者到底有什么样的区别呢

    浅析Java集合及LIst接口

    主要介绍了Java集合及LIst接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    浅析Android手机卫士保存手机安全号码

    推荐阅读: 浅析Android手机卫士sim卡绑定 深入浅析Android手机卫士保存密码时进行md5加密 详解Android 手机卫士设置向导页面 浅析Android手机卫士关闭自动更新 浅析Android手机卫士自定义控件的属性 ...调用List对

    深入浅析MySQL COLUMNS分区

    COLUMN分区是5.5开始引入的分区功能,只有RANGE COLUMN和LIST COLUMN这两种分区;支持整形、日期、字符串;RANGE和LIST的分区方式非常的相似。 COLUMNS和RANGE和LIST分区的区别 1.针对日期字段的分区就不需要再使用...

    python中的列表推导浅析

    列表推导(List comprehension)的作用是为了更方便地生成列表(list)。 比如,一个list变量的元素均为数字,如果需要将每个元素的值乘以2并生成另外一个list,下面是一种做法:复制代码 代码如下:#-*-encoding:utf...

    浅析JS中的 map, filter, some, every, forEach, for in, for of 用法总结

    let list = [1, 2, 3, 4, 5]; let other = list.map((d, i) =&gt; { return d * 2; }); console.log(other); // print: [2, 4, 6, 8, 10] 2.filter 有返回值,返回一个符合func条件的元素数组 let list = [1, 2, 3, 4...

    unix分析关于UNIX的一些浅析

    内核版本:2.6.31.6 ... static void __init smdk2440_machine_init(void) ... s3c24xx_fb_set_platdata(&smdk2440_fb_info);... platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));...

    浅析python中的迭代与迭代对象

    如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。 (在Python中,迭代是通过for … in来完成的) Python的for循环抽象程度要高于C的for循环,因为Python的...

    浅析python函数式编程

    目录 map filter reduce zip sortedmap map 其中,function 参数表示要传入一个函数,其可以是内置函数、自定义函数或者 lambda 匿名函数;...print(list(new_list)) filter filter() 函数的功能是对

    Mysql数据表分区技术PARTITION浅析

    主要介绍了Mysql数据表分区技术PARTITION浅析,分别介绍了 Mysql 中的分区技术 RANGE、LIST、 HASH,需要的朋友可以参考下

    浅析php过滤html字符串,防止SQL注入的方法

    数据过滤函数复制代码 代码如下:function stripslashes_array(&$array) { while(list($key,$var) = each($array)) { if ($key != ‘argc’ && $key != ‘argv’ && (strtoupper($key) != $key || ”.intval($key) ...

    浅析C++11新特性的Lambda表达式

    [capture list] (parameter list) -&gt; return type { function body } 可以看到,他有四个组成部分:  1.capture list: 捕获列表  2.parameter list: 参数列表  3.return type: 返回类型  4.function body...

Global site tag (gtag.js) - Google Analytics