当前位置: 首页 > news >正文

宁波网站建设公司制作网站/做什么推广最赚钱

宁波网站建设公司制作网站,做什么推广最赚钱,电力网站建设方案,做苗木网站哪家做得好为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表形成环形数据结构,查找时会陷入死循环。(1)当往H…

e7973d102abca574e14f2f5d188f81a1.png

为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表形成环形数据结构,查找时会陷入死循环。

(1)当往HashMap中添加元素时,会引起HashMap容器的扩容,原理不再解释,直接附源代码,如下:

/**  *  * 往表中添加元素,如果插入元素之后,表长度不够,便会调用resize方法扩容  */    void addEntry(int hash, K key, V value, int bucketIndex) {    Entry<K,V> e = table[bucketIndex];    table[bucketIndex] = new Entry<K,V>(hash, key, value, e);    if (size++ >= threshold)    resize(2 * table.length);    }    /**  * resize()方法如下,重要的是transfer方法,把旧表中的元素添加到新表中 */    void resize(int newCapacity) {    Entry[] oldTable = table;    int oldCapacity = oldTable.length;    if (oldCapacity == MAXIMUM_CAPACITY) {    threshold = Integer.MAX_VALUE;    return;    }    Entry[] newTable = new Entry[newCapacity];    transfer(newTable);    table = newTable;    threshold = (int)(newCapacity * loadFactor);    }    

(2)参考上面的代码,便引入到了transfer方法,(引入重点)这就是HashMap并发时,会引起死循环的根本原因所在,下面结合transfer的源代码,说明一下产生死循环的原理,先列transfer代码(这是里JDK7的源偌),如下:

/** * Transfers all entries from current table to newTable. */  void transfer(Entry[] newTable, boolean rehash) {  int newCapacity = newTable.length;  for (Entry<K,V> e : table) {  while(null != e) {  Entry<K,V> next = e.next;            ---------------------(1)  if (rehash) {  e.hash = null == e.key ? 0 : hash(e.key);  }  int i = indexFor(e.hash, newCapacity);   e.next = newTable[i];  newTable[i] = e;  e = next;  } // while  }  }  

(3)假设:

Map<Integer> map = new HashMap<Integer>(2);  // 只能放置两个元素,其中的threshold为1(表中只填充一个元素时),即插入元素为1时就扩容(由addEntry方法中得知)  //放置2个元素 3 和 7,若要再放置元素8(经hash映射后不等于1)时,会引起扩容  

假设放置结果图如下:

75d8f8c29ccc8f156b2acf9b76c546be.png

现在有两个线程A和B,都要执行put操作,即向表中添加元素,即线程A和线程B都会看到上面图的状态快照

执行顺序如下:
执行一: 线程A执行到transfer函数中(1)处挂起(transfer函数代码中有标注)。此时在线程A的栈中

e = 3    
next = 7

执行二:线程B执行 transfer函数中的while循环,即会把原来的table变成新一table(线程B自己的栈中),再写入到内存中。如下图(假设两个元素在新的hash函数下也会映射到同一个位置)

75e548dc2dd4fb99741a3adadd841446.png

执行三: 线程A解挂,接着执行(看到的仍是旧表),即从transfer代码(1)处接着执行,当前的 e = 3, next = 7, 上面已经描述。

1.处理元素 3 , 将 3 放入 线程A自己栈的新table中(新table是处于线程A自己栈中,是线程私有的,不肥线程2的影响),处理3后的图如下:

556398fd597840e861e018a4aead45d7.png

2.线程A再复制元素 7 ,当前 e = 7 ,而next值由于线程 B 修改了它的引用,所以next 为 3 ,处理后的新表如下图

9f85ee63c2ca93175085e523b5edba7e.png

3.由于上面取到的next = 3, 接着while循环,即当前处理的结点为3, next就为null ,退出while循环,执行完while循环后,新表中的内容如下图:

15525ee364b298a0ab3bcd9deee32abd.png

4.当操作完成,执行查找时,会陷入死循环!

最后

感谢大家看到最后,如文章有不足,欢迎大家在评论区支持,给予意见。如果觉得我的文章对你有帮助,那就给我一个赞同吧。

每天都会分享java相关技术文章或行业资讯。欢迎大家关注和转发文章。

http://www.jmfq.cn/news/4858471.html

相关文章:

  • 建立网站基本知识/百度网站网址是多少
  • 最超值的郑州网站建设/永久免费二级域名申请
  • 网站建设研究的意义/google搜索引擎入口网址
  • 电子商务网站建设规划的内容/电商运营转行后悔了
  • app开发公司电话/seo关键词推广
  • 网络平台怎么搭建网站/如何搜索关键词热度
  • 动态网站开发语言介绍/网络营销工作内容
  • 线下引流的八种推广方式/seo如何优化网站步骤
  • 龙岩亿网行/重庆seo黄智
  • 中国少数民族网站建设/新型网络营销方式
  • 修改wordpress上传文件限制/seo值是什么意思
  • 郑州网站制作天强科技/免费智能seo收录工具
  • 认识网络营销/网站关键词快速优化
  • 网站搜索推广方案论文/百度免费发布信息
  • 湛江低价网站建设/seo排名点击器
  • 怎么用dede建设网站/seo专员工作内容
  • 做网站的好处/百度搜一下
  • 网站如何调用手机淘宝做淘宝客/各引擎收录查询
  • 腾讯云建站流程/全网最全搜索引擎app
  • 合肥有哪些做网站的公司/百度seo排名工具
  • 东莞齐诺做网站/什么网站都能进的浏览器
  • 英语网站online/什么是关键词推广
  • 公司做的网站过期了/网络营销技巧培训班
  • 郑州网站优化托管/农产品营销方案
  • 万网虚拟服务器怎么做网站内容/中国搜索引擎大全
  • 网站管理服务/比优化更好的词是
  • 图片 网站开发/市场监督管理局
  • 高端广告公司名字/北京专门做seo
  • wordpress4.6 中文/上海全国关键词排名优化
  • 网站解析/种子搜索引擎在线