1.LinkedList源码分析

LinkedList的是基于链表实现的java集合类,通过index插入到指定位置的时候使用LinkedList效率要比ArrayList高,以下源码分析是基于JDK1.8.

1.1 类的继承结构

LinkedList类的继承结构如如下所示:

从以上继承结构图中可以看到,最顶层接口为Iterable接口,实现此接口的类支持通过迭代器遍历集合中的元素。其他相关接口如Collection、List、Queue、Deque分别为列表,队列功能的相关接口,即此LinkedList支持列表、队列的相关操作。Serializable接口为序列化标志接口,即所有需要序列化的类都需要实现此接口。

1.2 LinkedList数据结构说明

首先我们来看下LinkedList中保存数据的内部类定义源码如下:

private static class Node<E> {
E item;
Node<E> next;
Node<E> prev; Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

通过以上定义可以看出来每个节点中除了保存元素的值之外还保存了前后节点的引用。即使用了链表的数据接口保存数据元素。数据结构如下图所示:

在LinkedList类中,只是定义了两个Node类型的属性,定义如下:

 transient Node<E> first;
transient Node<E> last;

这两个属性分别表示头节点和尾节点,始终指向链表的第一个节点和最后一个节点。

1.3 关键方法源码分析

当不指定index往LinkedList中添加元素的时候默认是在链表的尾部添加数据,源代码如下

  void linkLast(E e) {
//保存链表插入之前的最后一个节点
final Node<E> l = last;
//将新节点的preNode指向链表最后一个节点
final Node<E> newNode = new Node<>(l, e, null);
last指向插入后的尾节点
last = newNode;
if (l == null)
//当第一次插入数据的时候,头节点和尾节点指向同一个节点
first = newNode;
else
//插入之前的尾节点的nextNode指向新插入的节点
l.next = newNode;
size++;
modCount++;
}

插入节点的详细操作如上面代码注释。在次操作中其实last即尾节点是共享资源,当多个线程同时执行此方法的时候,其实会出现线程安全问题。具体的线程安全问题后面分析。

当指定index插入数据的时候,源代码如下所示:

public void add(int index, E element) {
checkPositionIndex(index); if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}

在指定index插入元素的时候会先查询出index位置的元素,然后调用linkBefore将此元素插入到查询到的元素的前一个位置。其中linkBefore源码如下所示:

void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
//新建节点,并将preNode指向idnex-1节点
final Node<E> newNode = new Node<>(pred, e, succ);
//插入前的index节点的prev指向新节点
succ.prev = newNode;
if (pred == null)
first = newNode;
else
//index-1节点的nextNode指向新节点
pred.next = newNode;
size++;
modCount++;
}

在指定节点插入的方式如上注释所示。此操作中共享资源是插入之前index节点。同样会出现并发安全问题,下面对此问题进行分析。

2.LinkedList并发插入时节点覆盖的问题

在指定index插入或者addLast的时候都是在链表的尾部插入数据,当并发插入的时候如果出现以下执行顺序的时候,会出现插入的数据被覆盖的问题。

当多个线程同时获取到相同的尾节点的时候,然后多个线程同时在此尾节点后面插入数据的时候会出现数据覆盖的问题。

LinkedList源码和并发问题分析的更多相关文章

  1. ArrayList 和 LinkedList 源码分析

    List 表示的就是线性表,是具有相同特性的数据元素的有限序列.它主要有两种存储结构,顺序存储和链式存储,分别对应着 ArrayList 和 LinkedList 的实现,接下来以 jdk7 代码为例 ...

  2. java集合系列之LinkedList源码分析

    java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...

  3. java基础解析系列(十)---ArrayList和LinkedList源码及使用分析

    java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...

  4. Android版数据结构与算法(三):基于链表的实现LinkedList源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. LinkedList 是一个双向链表.它可以被当作堆栈.队列或双端队列进行操作.LinkedList相对于ArrayList来说,添加,删除元素效 ...

  5. LinkedList源码分析和实例应用

    1. LinkedList介绍 LinkedList是继承于AbstractSequentialList抽象类,它也可以被当作堆栈.队列或者双端队列使用. LinkedList实现了Deque接口,即 ...

  6. Java集合之LinkedList源码分析

    概述 LinkedLIst和ArrayLIst一样, 都实现了List接口, 但其内部的数据结构不同, LinkedList是基于链表实现的(从名字也能看出来), 随机访问效率要比ArrayList差 ...

  7. Java入门系列之集合LinkedList源码分析(九)

    前言 上一节我们手写实现了单链表和双链表,本节我们来看看源码是如何实现的并且对比手动实现有哪些可优化的地方. LinkedList源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...

  8. Java集合基于JDK1.8的LinkedList源码分析

    上篇我们分析了ArrayList的底层实现,知道了ArrayList底层是基于数组实现的,因此具有查找修改快而插入删除慢的特点.本篇介绍的LinkedList是List接口的另一种实现,它的底层是基于 ...

  9. 从面试角度分析LinkedList源码

    注:本系列文章中用到的jdk版本均为java8 LinkedList类图如下: LinkedList底层是由双向链表实现的.链表好比火车,每节车厢包含了车厢和连接下一节车厢的连接点.而双向链表的每个节 ...

随机推荐

  1. 27.C++- 智能指针

    智能指针 在C++库中最重要的类模板之一 智能指针实际上是将指针封装在一个类里,通过对象来管理指针. STL中的智能指针auto_ptr 头文件: <memory> 生命周期结束时,自动摧 ...

  2. 老男孩python学习之作业二---三级菜单

    因为之前花力气完成了购物小程序的作业 现在做这个三级菜单简直是so easy!! 1.显示省级菜单 2.交互,提示用户输入要查看的省份(退出e) 2.1.用户正确输入列表中的省份 3.显示市级菜单 3 ...

  3. Django(博客系统):基于pycharm如何一个django工程下创建多个app

    背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...

  4. win10 apache配置虚拟主机后localhost无法使用

    win10系统配置虚拟主机1.用记事本或Sublime Text打开httpd.confctrl + f 搜索httpd-vhosts.conf 将#Include conf/extra/httpd- ...

  5. [转]最常用的15大Eclipse开发快捷键技巧

    作者:Java我人生(陈磊兴)   原文出处http://blog.csdn.net/chenleixing/article/details/44600587 做Java开发的,经常会用Eclipse ...

  6. 利用typescript生成Swagger文档

    项目地址:https://github.com/wz2cool/swagger-ts-doc demo代码地址:https://github.com/wz2cool/swagger-ts-doc-de ...

  7. Extensions in UWP Community Toolkit - ListViewExtensions

    概述 UWP Community Toolkit Extensions 中有一个为 ListView 提供的扩展 - ListViewExtensions,本篇我们结合代码详细讲解 ListView  ...

  8. Unity中的基础光照

    渲染包含了两大部分:决定一个像素的可见性,决定这个像素上的光照计算. 光照模型就是用于决定在一个像素上进行怎样的光照计算. 一.光源 在实时渲染中我们通常把光源当做一个没有体积的点. 1.1 辐照度 ...

  9. springboot集成mybatis(二)

    上篇文章<springboot集成mybatis(一)>介绍了SpringBoot集成MyBatis注解版.本文还是使用上篇中的案例,咱们换个姿势来一遍^_^ 二.MyBatis配置版(X ...

  10. 在一个没有设置宽高的容器中,为什么设置position:absolute后就可以全屏显示了?

    此场景适用于移动端百分比布局,背景全屏显示. 在一个没有设置宽高的容器中设置背景,想要背景全屏显示,设置bcakground-size:100%;后还需设置position:absolut; 原因: ...