本站提倡有节制游戏,合理安排游戏时间,注意劳逸结合。

【成本分布主图指标源码】【网站电话源码】【代理api源码】linkedlist add源码

2024-12-29 20:01:16 来源:焦点 分类:焦点

1.List LinkedList HashSet HashMap底层原理剖析
2.线程安全的list之synchronizedList和CopyOnWriteArrayList

linkedlist add源码

List LinkedList HashSet HashMap底层原理剖析

       ArrayList底层数据结构采用数组。数组在Java中连续存储,因此查询速度快,时间复杂度为O(1),插入数据时可能会慢,特别是成本分布主图指标源码需要移动位置时,时间复杂度为O(N),但末尾插入时时间复杂度为O(1)。数组需要固定长度,ArrayList默认长度为,最大长度为Integer.MAX_VALUE。在添加元素时,如果数组长度不足,网站电话源码则会进行扩容。JDK采用复制扩容法,通过增加数组容量来提升性能。若数组较大且知道所需存储数据量,可设置数组长度,或者指定最小长度。代理api源码例如,设置最小长度时,扩容长度变为原有容量的1.5倍,从增加到。

       LinkedList底层采用双向列表结构。链表存储为物理独立存储,cdkey兑换源码因此插入操作的时间复杂度为O(1),且无需扩容,也不涉及位置挪移。然而,查询操作的时间复杂度为O(N)。LinkedList的创盟源码add和remove方法中,add默认添加到列表末尾,无需移动元素,相对更高效。而remove方法默认移除第一个元素,移除指定元素时则需要遍历查找,但与ArrayList相比,无需执行位置挪移。

       HashSet底层基于HashMap。HashMap在Java 1.7版本之前采用数组和链表结构,自1.8版本起,则采用数组、链表与红黑树的组合结构。在Java 1.7之前,链表使用头插法,但在高并发环境下可能会导致链表死循环。从Java 1.8开始,链表采用尾插法。在创建HashSet时,通常会设置一个默认的负载因子(默认值为0.),当数组的使用率达到总长度的%时,会进行数组扩容。HashMap的put方法和get方法的源码流程及详细逻辑可能较为复杂,涉及哈希算法、负载因子、扩容机制等核心概念。

线程安全的list之synchronizedList和CopyOnWriteArrayList

        在上篇文章中我们已经介绍了其他的一些list集合,如ArrayList、linkedlist等。不清楚的可以看下上篇文章 /p/ab5bf7

        但是向ArrayList这些会出现线程不安全的问题,我们该怎样解决呢?接下来就是要介绍我们线程安全的list集合synchronizedList和CopyOnWriteArrayList。

        synchronizedList的使用方式:

        从上面的使用方式中我们可以看出,synchronizedList是将List集合作为参数来创建的synchronizedList集合。

        synchronizedList为什么是线程安全的呢?

        我们先来看一下他的源码:

        我们大概贴了一些常用方法的源码,从上面的源码中我们可以看出,其实synchronizedList线程安全的原因是因为它几乎在每个方法中都使用了synchronized同步锁。

        synchronizedList官方文档中给出的使用方式是以下方式:

        在以上源码中我们可以看出,官方文档是建议我们在遍历的时候加锁处理的。但是既然内部方法以及加了锁,为什么在遍历的时候还需要加锁呢?我们来看一下它的遍历方法:

        从以上源码可以看出,虽然内部方法中大部分都已经加了锁,但是iterator方法却没有加锁处理。那么如果我们在遍历的时候不加锁会导致什么问题呢?

        试想我们在遍历的时候,不加锁的情况下,如果此时有其他线程对此集合进行add或者remove操作,那么这个时候就会导致数据丢失或者是脏数据的问题,所以如果我们对数据的要求较高,想要避免这方面问题的话,在遍历的时候也需要加锁进行处理。

        但是既然是使用synchronized加锁进行处理的,那肯定避免不了一些锁开销。有没有效率更好的方式呢?那就是我们另一个主要的并发集合CopyOnWriteArrayList。

        CopyOnWriteArrayList是在执行修改操作时,copy一份新的数组进行相关的操作,在执行完修改操作后将原来集合指向新的集合来完成修改操作。具体源码如下:

        从以上源码我们可以看出,它在执行add方法和remove方法的时候,分别创建了一个当前数组长度+1和-1的数组,将数据copy到新数组中,然后执行修改操作。修改完之后调用setArray方法来指向新的数组。在整个过程中是使用ReentrantLock可重入锁来保证不会有多个线程同时copy一个新的数组,从而造成的混乱。并且使用volatile修饰数组来保证修改后的可见性。读写操作互不影响,所以在整个过程中整个效率是非常高的。

        synchronizedList适合对数据要求较高的情况,但是因为读写全都加锁,所有效率较低。

        CopyOnWriteArrayList效率较高,适合读多写少的场景,因为在读的时候读的是旧集合,所以它的实时性不高。

相关推荐
一周热点