欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java面试基础篇-List

程序员文章站 2022-04-09 14:52:56
一.ArrayList: 底层为数组实现,线程不安全,查询,修改快,增加删除慢, 数据结构:数组以0为下标依次连续进行存储 数组查询元素:根据下标查询就行 数组增加元素:如果需要给index为10的位置添加,则从index为11的位置开始右移 数组删除元素:如果需要删除index为10的位置,则从i ......

一.arraylist:

  底层为数组实现,线程不安全,查询,修改快,增加删除慢,

数据结构:数组以0为下标依次连续进行存储

  数组查询元素:根据下标查询就行

  数组增加元素:如果需要给index为10的位置添加,则从index为11的位置开始右移

       数组删除元素:如果需要删除index为10的位置,则从index为11的位置开始左移

线程: 如果判断线程安不安全只需要了解到是否进行加锁,如果没有加锁的话,多个线程操作同一个对象时就会出现线程不安全的情况.

源码:

1.new一个arraylist,调用add方法

java面试基础篇-List

 

2.查看add方法的源码可以看出,并没有任何加锁操作,这就是线程不安全的 ,这里首先会确认数组的容量,对其进行增加,并将新的元素加入到数组中

java面试基础篇-List

 

 使用场景:查询 修改多

 

二.likedlist:

  底层为链表实现,线程不安全,查询修改慢,增加删除快

数据结构:链表的每个元素都存储了下一个元素的地址,从而使一系列的随机的内存地址串在了一起,只要有足够的内存空间,就可以为链表分配内存

  链表查:当同时读取所有元素时,链表的效率很高,读第一个,读第二个,以此类推。如果需要找到某个节点时,就需要遍历整个节点,才可以找到需要的元素

  链表增加元素:只需要修改它前面的那个元素指针指向的地址即可

  链表删除元素:只需要将前一个元素指针指向的地址更改即可

线程: 如果判断线程安不安全只需要了解到是否进行加锁,如果没有加锁的话,多个线程操作同一个对象时就会出现线程不安全的情况.

源码:

1.new一个likedlist

java面试基础篇-List

 

2.可以看到likedlist源码中也无任何的加锁操作,其中add又调用了linklast

java面试基础篇-List

 

3.linklast里会吧新加元素设置为尾节点,所以创建了一个新的node(节点)存起来,然后再新建一个节点,把之前的node指向链表的最后一个节点,然后再判断一下l是否为空也就是之前的链表里是否为空,如果为空则吧新的节点设为头节点,否则就把next改为newnode,同时size和modcound自增

同样的 也没看到任何加锁的操作

java面试基础篇-List

 

使用场景:增加删除多

 

 

三,vector 

  底层是数组实现,线程安全的,操作的时候使用synchronized进行加锁 

  因为是数组实现的,curd方面可以参考arraylist,由于是加锁的,所以比前两个list效率更低的

源码

1.new一个vector,

  java面试基础篇-List

 

 2. 可以看到这个方法使用了 synchronized来进行修饰,对此方法进行加锁,因此这个方法对元素操作时是效率安全的,但效率相对较低,

同样的首先确认元素,扩容+1,把新的元素放进去

  java面试基础篇-List

 

  

 

 

题外话.怎样来保证list的线程安全

  方式一:自己写一个包装类,根据业务,一般在进行add/update/remove操作时加锁

  方式二:collections调用 synchronizedlist方法,

源码:

1.创建一个list,会返回一个线程安全的list给你

  java面试基础篇-List

2.可看到这个方法里首先是一个list集合,mutex是一个加锁的对象

  java面试基础篇-List

3.在继续打开synchronizedrandomaccesslist

  java面试基础篇-List

 

4,打开super,这里可以看到这里返回了一个同步的synchronizedlist,同样也继承了一个list方法

  java面试基础篇-List

5.在synchronizedlist里可以找到常用的一些方法,同样也是加锁的,所以这个就变成线程安全了

  java面试基础篇-List

 

  方式三:copyonwritearraylist  

源码:

1.new copyonwritearraylist   使用reentrantlock加锁

  java面试基础篇-List

2. copyonwritearraylist 在使用get操作时没有加锁的 这个与synchronizedlist对比来说性能要更好一点

  java面试基础篇-List

3,在add方法时可以看到用了reentrantlock来进行加锁,再用object数组获取老的数组,并将老的数组获取保存在len,

下面再用arrays.copyof进行拷贝,将老的数组拷贝到新的数组newelements,并将长度+1,+1的原因就是为了存放新的元素,

目前内存里有两个空间,一个空间是新的空间,另一个是旧的空间

  java面试基础篇-List

  java面试基础篇-List

setarray是为了将新的拷贝到旧的里,也就是改变了他的引用地址

最终unlock,把锁释放