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

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

HashMap高并發死循環問題

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

當你研究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高并發死循環!

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

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 久久免费高清 | 国内精品视频 | 亚洲一区二区三区精品视频 | 射久久| 国产精品午夜激爽毛片 | 成人在线观看不卡 | 一级片视频网站 | 久草视频在线观 | 亚洲国产伦理 | 夜夜艹日日艹 | 风流一代在线播放 | 国外成人免费高清激情视频 | 精品国产精品国产 | 日本最猛黑人xxxx猛交 | 99视频国产热精品视频 | 亚洲美女啪啪 | 欧美性生交xxxxx丝袜 | 亚洲国产精品自产在线播放 | 久久精品国产999久久久 | 欧美一区二区三区播放 | 日韩一区二区视频在线观看 | 特级生活片 | 欧美韩国日本一区 | 不卡视频免费在线观看 | 四虎永久免费地址在线观看 | 激情五月宗合网 | 欧洲成人在线 | 在线中文字幕视频 | 国产精品成人四虎免费视频 | 亚洲免费高清视频 | 国产99在线播放免费 | 天天做人人爱夜夜爽2020 | 香蕉久人久人青草青草 | 成年女人视频免费观看一 | www日日日| 欧美精品专区第1页 | 天天操夜夜操天天操 | 亚洲激情视频 | 99热久久这里只有精品99 | 夜夜狠操| 九九热视频免费在线观看 |