当前位置: 首页 > 网络应用技术

Hashmap和ConcurrentHashmap面试点

时间:2023-03-06 14:34:55 网络应用技术

  JDK7:数组+链接列表

  JDK8:阵列+链接列表+红色和黑树(看过源代码的学生应该知道JDK8使用一个 - 路链接列表,还使用了两个路链接列表。两个 - 路链接列表主要是为了便利链接列表操作的lack树,红树和黑色树的链接列表必须操作链接列表)

  当元素的数量小于阈值时,链接列表的总体插入查询效率高于红树和黑树的总插入查询效率。当元素的数量大于此阈值时,链接列表的查询效率低于红色和黑树。此阈值在Hashmap中为8

  这个问题很容易回答。大多数答案是:当链接列表中的元素数量大于8时,链接列表将转换为红色和黑色树。但实际上,链接列表中的元素数量数量:大于8,它还将判断当前数组的长度。如果阵列的长度小于64,则目前不会将其转换为红色和黑色树,而是将进行。Expansion.Expansion。仅当链接列表中的元素数量大于8时,阵列的长度将把链接列表转换为红色和黑色树。上面扩展的原因是,如果数组的长度相对较小,则首先使用扩展来减少链接列表的长度。

  1.根据密钥生成哈希码

  2.确定当前hashmap对象中的数组是否为空。如果是空的,则将数组初始化

  3.根据逻辑和操作,根据与当前阵列相对应的阵列计算哈希码的投标。我

  4.确定数组的元素(tab [i])是否为空

  5.Modcount ++

  6. hashmap plus 1的元素数量1

  7.如果大小大于扩展的阈值,则容量会扩大

  1.根据密钥生成哈希码

  4.如果数组的i -i位置没有元素,请直接返回空

  5.如果数组的第一个位上的元素的键等于GET方法传递的密钥,则将返回元素并获得元素的值

  6.如果不等于确定该元素是否仍然是下一个元素,则返回到空

  7.如果有的话,可以确定此元素的类型是链接列表节点还是红色和黑色树节点

  一种。如果是链接列表

  b。如果是红树和黑树,它会穿越红色和黑树

  8.如果找到元素,请返回元素,如果找不到它,请返回空中

  1. JDK8中使用了红树和黑树

  2.在JDK7中插入链接列表的头部插入(当容量的容量扩展时,还使用头部插入方法,并且头部插入方法更快,不需要穿越链接列表。循环链接列表引起了CPU SOARING),这是JDK8中的链表使用的尾插入方法(在JDK8中,用于计算链接列表的当前节点的数量,无论如何,无论如何,都应旅行链接列表,因此请使用尾插法直接)

  3. JDK7的哈希算法比JDK8更为复杂。哈希算法越复杂,生成的哈希码更分散。红树和黑树,因此您只能优化哈希算法以使元素更大,然后将红色和黑树添加到JDK8中,并且查询性能性能较大。保证。因此,您可以简化哈希算法。

  4.在扩展过程中,JDK7可能会重新接合密钥的钥匙(重新与哈希种子有关),并且JDK8中没有这种逻辑

  5. JDK8中扩展的条件与JDK7不同。除了判断大小是否大于阈值外

  6. JDK8中还有一个API:putifabsent(键,值)

  7. JDK7和JDK8在扩展过程中,转移元件的逻辑不同。JDK7是每次转移元素。JDK8首先计算哪些元素位于新数组的低位置,该位置位于新数组的高位置,然后是新数组的高位置

  主要使用不安全的操作+重新输入lock+分段想法。务必使用不安全的操作:

  1.比较eareAreAndSwapObject:通过CAS方法修改对象的属性2. putserderedObject:对数组的某个位置的安全性3. getObjectVolatile:getObjectVolatile:阵列某个位置的元素的元素思想是增加并发症contrenthashmap并发症。

  段越高,最大并发量越高。程序员可以通过conturrencyLevel参数指定并发金额。concurrenthashmap的内部类段用于表示某个段落。EATEAST段是一个小的哈希图。当调整confurnThashMap的PUT方法最终被称为段的PUT方法,并且段类别继承了reentrantlock,因此该段带有该段的put方法。这次,您将使用锁定锁定锁第一的。锁成功后,将键的键插入要插入的键,并在插入后解锁。

  ConturrentHashMap底层是通过两层嵌套数组来实现的:1。conurrenthashmap对象具有属性段,类型为semgment [];

  2.段对象中有一个属性表,类型为[];

  当调用ConcurRentHashMap的PUT方法时,首先计算JTC JET J的相应段[]数组来确定应插入当前密钥中的哪个段对象。锁定方法在J位置中生成段对象。然后调用PUT。段对象的方法。

  段对象的put方法将首先锁定,然后基于键计算散列哈希[]的相应哈希的相应数组,然后封装键,值为该位置中的hashes对象。解锁。逻辑在锁定过程中更为复杂。首先,通过自旋锁,如果超过固定数字的数量,它将直接阻止和其他锁。

  主要使用不安全的操作+同步关键字。不安全操作的使用仍然与JDK7相似,JDK7主要负责属性或值的属性或值或并发安全性的某个位置的数组。

  同步主要负责锁定何时需要操作某个位置(位置不是空的),例如将节点插入某个位置的链接列表,然后将节点插入到某个位置的红色和黑色树上实际上,JDK8中仍然有分段锁,但是可以控制JDK7的中间数,并且JDK8中数组的每个位置都锁定。

  放置钥匙时,在consurrenthashmap中的价值,

  1.首先根据密钥计算数组i的相应数组。如果该位置没有元素,则将通过旋转分配给位置。

  2.如果此位置有元素,则同步将被锁定

  3.锁成功后,判断元素a的类型。如果是链接列表节点,请在链接列表B中添加节点。如果是红色和黑色树

  4.添加成功后,确定是否需要对其进行处理

  5.添加,此方法意味着ConcurrenthAshmap Plus 1的要素数量,但是此操作也需要并发安全性,并且在成功的元素数量成功之后,它将继续确定是否扩大容量。如有必要,它将扩大容量。因此,此方法很重要。

  6.同时,如果在PUT中找到线程,则发现当前的ConturrentHashMap正在扩展,它将有助于扩展。

  这两者之间存在太多差异。...包括哈希图和其他差异的差异,例如:

  1. JDK8中没有片段锁,但使用同步进行控制

  2. JDK8中的扩展性能更高,同时支持多线程扩展。实际上,JDK7还支持多线程扩展。因为JDK7中的扩展适用于每个分段的高潮,因为JDK8可以帮助扩展JDK8中的任何线程

  3. JDK8中的元素数与实现元素数量的数量不同。将countrcell添加到DK8中以帮助计数,并且在将JDK7置于jdk7时,每个细分市场都没有内部计数。

  当然,还有一个小点优化措施。要在这里出售它,您需要更多地关注微信公共帐户“老挝”。

  原来的;https://juejin.cn/post/7097147987058491423