Java并发

论坛 期权论坛     
选择匿名的用户   2021-5-30 02:11   74   0
<h1>1、HashMap</h1>
<p><img alt="图片" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-feaaadf5fbda134b66bcc118c0b81915.png"></p>
<p>面试第一题必问的 <a href="https://mp.weixin.qq.com/s?__biz&#61;MzI4NjI1OTI4Nw&#61;&#61;&amp;mid&#61;2247485513&amp;idx&#61;1&amp;sn&#61;340e879f3197ae9e3d8789a1ad55a76e&amp;scene&#61;21#wechat_redirect">HashMap</a>,挺考验<strong>Javaer</strong>的基础功底的,别问为啥放在这,因为重要!HashMap具有如下<strong>特性</strong>:</p>
<blockquote>
<ol><li> <p>HashMap 的存取是没有顺序的。</p> </li><li> <p>KV 均允许为 NULL。</p> </li><li> <p>多线程情况下该类不安全,可以考虑用 HashTable。</p> </li><li> <p>JDk8底层是数组 &#43; 链表 &#43; 红黑树,JDK7底层是数组 &#43; 链表。</p> </li><li> <p>初始容量和装载因子是决定整个类性能的关键点,轻易不要动。</p> </li><li> <p>HashMap是<strong>懒汉式</strong>创建的,只有在你put数据时候才会 build。</p> </li><li> <p>单向链表转换为红黑树的时候会先变化为<strong>双向链表</strong>最终转换为<strong>红黑树</strong>,切记双向链表跟红黑树是<code>共存</code>的。</p> </li><li> <p>对于传入的两个<code>key</code>,会强制性的判别出个高低,目的是为了决定向左还是向右放置数据。</p> </li><li> <p>链表转红黑树后会努力将红黑树的<code>root</code>节点和链表的头节点 跟<code>table[i]</code>节点融合成一个。</p> </li><li> <p>在删除的时候是先判断删除节点红黑树个数是否需要转链表,不转链表就跟<code>RBT</code>类似,找个合适的节点来填充已删除的节点。</p> </li><li> <p>红黑树的<code>root</code>节点<code>不一定</code>跟<code>table[i]</code>也就是链表的头节点是同一个,三者同步是靠<code>MoveRootToFront</code>实现的。而<code>HashIterator.remove()</code>会在调用<code>removeNode</code>的时候<code>movable&#61;false</code>。</p> </li></ol>
</blockquote>
<p>常见HashMap考点:</p>
<blockquote>
<ol><li> <p>HashMap原理,内部数据结构。</p> </li><li> <p>HashMap中的put、get、remove大致过程。</p> </li><li> <p>HashMap中 hash函数实现。</p> </li><li> <p>HashMap如何扩容。</p> </li><li> <p>HashMap几个重要参数为什么这样设定。</p> </li><li> <p>HashMap为什么线程不安全,如何替换。</p> </li><li> <p>HashMap在JDK7跟JDK8中的区别。</p> </li><li> <p>HashMap中链表跟红黑树切换思路。</p> </li><li> <p>JDK7中 <a href="https://mp.weixin.qq.com/s?__biz&#61;MzI4NjI1OTI4Nw&#61;&#61;&amp;mid&#61;2247485348&amp;idx&#61;1&amp;sn&#61;fed45652fa26f374b5229b401e74ca2c&amp;scene&#61;21#wechat_redirect">HashMap环产生原理</a>。</p> </li></ol>
</blockquote>
<h1>2、ConcurrentHashMap</h1>
<p><a href="https://mp.weixin.qq.com/s?__biz&#61;MzI4NjI1OTI4Nw&#61;&#61;&amp;mid&#61;2247487563&amp;idx&#61;1&amp;sn&#61;0a223ae2bba963e3ac40b7ce6d9ecd56&amp;scene&#61;21#wechat_redirect">ConcurrentHashMap</a> 是多线程模式下常用的并发容器,它的实现在<strong>JDK7</strong>跟<strong>JDK8</strong>区别挺大的。</p>
<h3>2.1 JDK7</h3>
<p><strong>JDK7</strong>中的 <a href="https://mp.weixin.qq.com/s?__biz&#61;MzI4NjI1OTI4Nw&#61;&#61;&amp;mid&#61;2247487563&amp;idx&#61;1&amp;sn&#61;0a223ae2bba963e3ac40b7ce6d9ecd56&amp;scene&#61;21#wechat_redirect">ConcurrentHashMap</a> 使用 <strong>Segment</strong> &#43; <strong>HashEntry</strong> 分段锁实现并发,它的<strong>缺点</strong>是并发程度是由<strong>Segment</strong> 数组个数来决定的,并发度一旦初始化无法扩容,扩容的话只是<strong>HashEntry</strong>的扩容。<img alt="图片" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-44e2f6165c251c038132e9e92f70603c.png"><strong>Segment</strong> 继承自 <strong>ReentrantLock</strong>,在此扮演锁的角色。可以理解为我们的每个<strong>Segment</strong>都是实现了<strong>Lock</strong>功能的<strong>HashMap</strong>。如果我们同时有多个<strong>Segment</strong>形成了<strong>Segment</strong>数组那我们就可以实现并发咯。</p>
<p>大致的<strong>put</strong>流程如下:<img alt="图片" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-4619e0167518d77d87f9fb6913860b1f.png"></p>
<ol><li> <p><strong>ConcurrentHashMap</strong>底层大致实现?</p> </li></ol>
<blockquote>
<p>ConcurrentHashMap允许多个修改操作<strong>并发进行</strong>,其关键在于使用了<code>锁分离技术</code>。它使用了多个锁来控制对hash表的不同部分进行的修改。内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的HashTable,只要多个修改操作发生在不同的段上就可以并发进行。</p>
</blockquote>
<ol><li> <p><strong>ConcurrentHashMap</strong>在并发下的情况下如何保证取得的元素是最新的?</p> </li></ol>
<blockquote>
<p>用于存储键值对数据的<strong>HashEntry</strong>,在设计上它的成员变量<strong>value</strong>跟<strong>next</strong>都是<code>volatile</code>类型的,这样就保证别的线程对valu
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP