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. mysql中独立表空间与共享表空间之前如何切换

    环境 mysql版本:5.7.19 官方文档:(https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) 查看 ...

  2. 关于HTML

    我的PHP学习之旅 学习PHP已经有一段时间了,今天才想好好的总结一下这一路走来的点点滴滴,也想把我的学习方法及经验分享给大家,希望能对你有所帮助. 首先学习的是PHP前端部分,这里需要学习的知识有H ...

  3. 如何把百度统计代码放入JS文件中?百度统计的JS脚本原理分析

    <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script&quo ...

  4. logging格式

    import logging def foo(s): return 10 / int(s) def bar(s): return foo(s) * 2 def main(): try: bar(0) ...

  5. docker 安装与学习

    本文在CentsOS下安装Docker 1.安装前准备工作 系统要求: 在CentOS下需要64位的CentsOS 7   OS requirements To install Docker, you ...

  6. 医疗器械c#上位机开发指引教程

    此教程面向的读者:对医疗器械上位机编程有兴趣,或者急需了解医疗器械(尿常规.血液分析.生化.心电.B超等医疗下位仪器)的编程流程.编程细节的程序员. 1.得到仪器协议 当我们需要与医疗器械等下位机数据 ...

  7. HttpClient入门二

    通过上一节我们已经可以实现对一个网站源码的抓取. 但是,有一些网站,在爬取的时候会出现如下的错误: HTTP/1.1 503 Service Unavailable <!DOCTYPE html ...

  8. [BZOJ 2169]连边

    Description 有N个点(编号1到N)组成的无向图,已经为你连了M条边.请你再连K条边,使得所有的点的度数都是偶数.求有多少种连的方法.要求你连的K条边中不能有重边,但和已经连好的边可以重.不 ...

  9. [HAOI2007]覆盖问题

    题目描述 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定 用3个L*L的正方形塑料薄膜将小树遮起来.我 ...

  10. 【JZOJ4307】喝喝喝

    Description solution 正解:尺取法. 很容易想到尺取法,维护左右指针,\(a[i]\%a[j]==K\),当且仅当 \(a[j]>K\) 并且 \(a[i]-K\) 的约数中 ...