大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 HashMap高并發死循環問題

HashMap高并發死循環問題

更新時間:2022-01-05 10:39:22 來源:動力節點 瀏覽862次

當你研究Java并發送一個容器和框架時,當你想使用ConcurrentHashMap時,原因之一是:HashMap中的線程是不安全的,并發執行PUT操作時會導致死亡循環,因為多線程會導致Hashmap的entry 鏈表構成環形數據結構,一看就會陷入死循環。

1.HashMap添加元素時,HashMap容器??的擴展會導致原理不再解釋,直接附上代碼,如下:

/** 
    * 
        * Add elements to the table. If the element is inserted, the Table length is not enough, and the resize method will be called. 
    */  
   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 () method is as follows, it is important to add the elements in the old table to a new table.
    */  
   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方法,(介紹)這就是造成死循環的根本原因,結合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);  // Only two elements can be placed, where Threshold is 1 (when only one element is filled in the table), that is, the insertion element is 1 when the element is 1 (known by the Addentry method)
// Place 2 elements 3 and 7, to place the element 8 (not equal to 1 after the Hash mapping), can cause expansion

假設放置結果如下:

現在有兩個線程A和B,都實現了,即向表中添加元素,即線程a和線程b會看到上面的狀態快照。

執行順序如下:

Execute 1:線程A在Transfer function(1)中執行(在Transfer function代碼中標注)。此時棧中的線程a

e = 3
next = 7

執行2:線程B 執行Transfer函數中的While循環,將原表變成新表(線程b自己的棧),然后寫入內存。如下圖(假設新的Hash函數下兩個元素會映射到同一個位置)

執行三:線程A敲了,然后執行(還是老表看到的),即從Transfer代碼(1),當前E=3,Next=7,上面已經說明了。

(1)處理元素3,將3放入線程A棧中的新表中(新表在線程A棧中,是線程私有的影響,未施肥線程2),處理3后的繪圖3如下:

(2)線程A復制了元素7,當前E=7,由于線程b被修改,next值已經修改了它的引用,所以NEXT為3,處理后的新表如下圖。

(3)由于上面的next=3,那么While循環,即當前進程為3,next為NULL,退出while循環,執行While循環后,new表中的內容如下:

(4)操作完成后會陷入HashMap高并發死循環!

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 天天草b | 欧美亚洲国产成人高清在线 | 国产亚洲精品激情一区二区三区 | 一 级 黄 中国色 片 | 国内精品视频在线播放一区 | 国产精品分类视频分类一区 | 香蕉视频一级片 | 欧美日韩国产欧美 | 日韩欧美色视频 | 曰本毛片 | 久亚洲精品不子伦一区 | 免费黄色小视频在线观看 | 欧美成人aaa大片 | 国产xxxx做受性欧美88 | 亚洲在线免费视频 | 国产永久在线观看 | 中文字幕一区在线观看 | 久久精品综合一区二区三区 | 国产日韩欧美在线一区二区三区 | 亚洲日韩精品欧美一区二区 | 日日摸夜夜 | 91粉嫩萝控精品福利网站 | 天天操夜夜操免费视频 | 成人午夜大片免费视频77777 | 一区二区三区在线 | 网站 | 色综合成人丁香 | 久久99国产亚洲高清观看韩国 | 国产伦精品一区二区免费 | 色操网 | 亚洲成人免费观看 | 2020久久精品永久免费 | 欧美成人香蕉在线观看 | 一区二区在线播放福利视频 | 91精品全国免费观看 | 日韩在线免费视频 | 狠狠操亚洲 | 在线亚洲黄色 | 久久宗合色 | 夜夜嗨影院 | 五月综合色 | 视频一区在线免费观看 |