`

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
分享到:
评论

相关推荐

    list.h 浅谈 手把手教你

    《Linux内核中的list.h浅析:手把手教学》 在Linux内核编程中,`list.h`头文件是处理链表数据结构的关键。本文将深入探讨`list.h`中的核心概念,帮助开发者理解如何有效地操作链表。 链表作为一种基础的数据结构,...

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

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

    SFTP 源码浅析1

    `connect_to_server`函数利用`socketpair`创建套接字,并通过`fork`创建子进程,子进程调用`execvp`执行ssh程序,以`args.list`作为参数,与目标主机建立连接。服务器端的sshd守护进程响应连接,启动`sftp-server`...

    MTK平台CAMERA驱动浅析

    ### MTK平台CAMERA驱动浅析 #### 一、手机CAMERA的物理结构: 手机摄像头(CAMERA)由多个部分组成,主要包括以下几个核心组件: - **FPC (Flexible Printed Circuit)**:柔性印刷电路板,用于连接摄像头各个部件...

    Redis架构下的MySQL数据库性能提升浅析.pdf

    Redis 中提供了五种基本数据结构,即字符串(string)、列表(list)、哈希(hash)、集合(set)和有序集合(sorted set)。 IV. Redis 中的数据结构选择 经过调研,发现适合存储行的数据结构有两种,即 string ...

    Linux内核bridge浅析.doc

    net_bridge结构中有一个port_list成员,用于维护网桥设备的端口列表,每个端口对应一个以太网接口设备。 网桥数据包处理流程 网桥数据包处理流程主要包括接收过程和转发过程。接收过程中,网口设备接收到的报文...

    浅析Java泛型的使用.pdf

    它允许我们在编写代码时指定容器(如List、Set、Map等)能存储何种类型的元素,从而避免运行时的类型转换异常,并在编译阶段就检查出类型错误。 在Java中,泛型并非协变的。这意味着如果Integer是Number的子类,...

    Java 观察者模式的浅析

    具体主题实现抽象主题接口,通常使用一个`Vector`或`List`来保存观察者对象。具体主题的实现代码如下: ```java import java.util.Vector; import java.util.Enumeration; public class ConcreteSubject ...

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

    在C#编程语言中,数组、ArrayList和List都是用来存储一组对象的数据结构,但它们之间存在着显著的差异。 首先,数组是最基础的数据结构,它在内存中以连续的方式存储元素,提供直接通过索引访问元素的能力。数组的...

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

    在Python编程语言中,列表(list)是一种非常灵活和常用的复合数据类型。我们经常需要复制一个列表到另一个变量,而在复制过程中涉及到的深拷贝(deep copy)和浅拷贝(shallow copy)是两个重要的概念。理解它们...

    浅析Java集合及LIst接口

    "Java集合及List接口详解" Java集合是Java语言中的一种数据结构,用于存储和操作数据。Java集合可以分为两大类:Collection和Map。Collection接口是所有集合的父接口,它提供了基本的集合操作,如add、remove、...

    Oracle_TNS浅析.doc

    ### Oracle TNS浅析 #### 一、Oracle TNS简介 **TNS( Transparent Network Substrate)** 是Oracle Net的一部分,主要用于管理和配置Oracle数据库与客户端之间的连接。它为客户端提供了透明的网络通信机制,使得...

    电子邮件协议浅析

    ### 电子邮件协议浅析 #### 一、电子邮件系统概述 电子邮件作为一种重要的通信工具,自1972年由BBN的Ray Tomlinson发明以来,已经成为全球范围内信息传递的重要方式之一。电子邮件不仅具备传递迅速的特点,还能...

    Java 集合浅析.txt

    ### Java集合浅析 #### 一、概述 Java集合框架是Java编程语言中处理数据结构的一个强大工具包,它提供了一系列灵活高效的接口和实现来帮助开发者管理数据。本篇文章将重点介绍Java中常用的集合类——`Collection`...

    linux网络报文接收发送浅析分享.pdf

    "Linux 网络报文接收发送浅析分享" 本文档主要介绍了 Linux 内核中网络报文的接收和发送机制。网络报文的接收是通过网络设备驱动程序从网络设备中读取报文,然后通过内核提供的网络接口函数将报文传递到内核中的...

    zookeeper浅析

    ### Zookeeper浅析 #### Zookeeper简介 Zookeeper是一个开源的分布式协调服务,它主要用于解决分布式应用程序中的常见问题,如配置管理、命名服务、分布式同步等。与传统的进程内协调不同,Zookeeper针对的是分布式...

    PHP程序安全浅析.pdf

    PHP 程序安全浅析 SQL 注入攻击是现今黑客采用的较多的手法之一,造成的危害也极其严重。本文就流行的 PHP 语言结合实际应用中的系统,来谈谈导致攻击的原因,并探讨了其防范措施。 一、关键词解释 * PHP:一种...

Global site tag (gtag.js) - Google Analytics