真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何淺析ConcurrentHashMap

如何淺析ConcurrentHashMap,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)建站不只是一家網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司;我們對(duì)營(yíng)銷、技術(shù)、服務(wù)都有自己獨(dú)特見解,公司采取“創(chuàng)意+綜合+營(yíng)銷”一體化的方式為您提供更專業(yè)的服務(wù)!我們經(jīng)歷的每一步也許不一定是最完美的,但每一步都有值得深思的意義。我們珍視每一份信任,關(guān)注我們的成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)質(zhì)量和服務(wù)品質(zhì),在得到用戶滿意的同時(shí),也能得到同行業(yè)的專業(yè)認(rèn)可,能夠?yàn)樾袠I(yè)創(chuàng)新發(fā)展助力。未來將繼續(xù)專注于技術(shù)創(chuàng)新,服務(wù)升級(jí),滿足企業(yè)一站式營(yíng)銷型網(wǎng)站建設(shè)需求,讓再小的成都品牌網(wǎng)站建設(shè)也能產(chǎn)生價(jià)值!

數(shù)據(jù)的可見性

直接進(jìn)入正題,concurrentHashMap相信用的人也很多,因?yàn)樵跀?shù)據(jù)安全性上確實(shí)比HashMap好用,在性能上比hashtable也好用。大家都知道線程在操作一個(gè)變量的時(shí)候,比如i++,jvm執(zhí)行的時(shí)候需要經(jīng)過兩個(gè)內(nèi)存,主內(nèi)存和工作內(nèi)存。那么在線程A對(duì)i進(jìn)行加1的時(shí)候,它需要去主內(nèi)存拿到變量值,這個(gè)時(shí)候工作內(nèi)存中便有了一個(gè)變量數(shù)據(jù)的副本,執(zhí)行完這些之后,再去對(duì)變量真正的加1,但是此時(shí)線程B也要操作變量,并且邏輯上也是沒有維護(hù)多線程訪問的限制,則很有可能在線程A在從主內(nèi)存獲取數(shù)據(jù)并在修改的時(shí)候線程B去主內(nèi)存拿數(shù)據(jù),但是這個(gè)時(shí)候主內(nèi)存的數(shù)據(jù)還沒有更新,A線程還沒有來得及講加1后的變量回填到主內(nèi)存,這個(gè)時(shí)候變量在這兩個(gè)線程操作的情況下就會(huì)發(fā)生邏輯錯(cuò)誤。

原子性

原子性就是當(dāng)某一個(gè)線程A修改i的值的時(shí)候,從取出i到將新的i的值寫給i之間線程B不能對(duì)i進(jìn)行任何操作。也就是說保證某個(gè)線程對(duì)i的操作是原子性的,這樣就可以避免數(shù)據(jù)臟讀。

volatile的作用

Volatile保證了數(shù)據(jù)在多線程之間的可見性,每個(gè)線程在獲取volatile修飾的變量時(shí)候都回去主內(nèi)存獲取,所以當(dāng)線程A修改了被volatile修飾的數(shù)據(jù)后其他線程看到的一定是修改過后最新的數(shù)據(jù),也是因?yàn)関olatile修飾的變量數(shù)據(jù)每次都要去主內(nèi)存獲取,在性能上會(huì)有些犧牲。

措施

HashMap在多線程的場(chǎng)景下是不安全的,hashtable雖然是在數(shù)據(jù)表上加鎖,縱然數(shù)據(jù)安全了,但是性能方面確實(shí)不如HashMap。那么來看看concurrentHashMap是如何解決這些問題的。

concurrentHashMap由多個(gè)segment組成,每一個(gè)segment都包含了一個(gè)HashEntry數(shù)組的hashtable, 每一個(gè)segment包含了對(duì)自己的hashtable的操作,比如get,put,replace等操作(這些操作與HashMap邏輯都是一樣的,不同的是concurrentHashMap在執(zhí)行這些操作的時(shí)候加入了重入鎖ReentrantLock),這些操作發(fā)生的時(shí)候,對(duì)自己的hashtable進(jìn)行鎖定。由于每一個(gè)segment寫操作只鎖定自己的hashtable,所以可能存在多個(gè)線程同時(shí)寫的情況,性能無疑好于只有一個(gè)hashtable鎖定的情況。通俗的講就是concurrentHashMap由多個(gè)hashtable組成。

源碼

看下concurrentHashMap的remove操作

V remove(Object key, int hash, Object value) {
            lock();//重入鎖
            try {
                int c = count - 1;
                HashEntry[] tab = table;
                int index = hash & (tab.length - 1);
                HashEntry first = tab[index];
                HashEntry e = first;
                while (e != null && (e.hash != hash || !key.equals(e.key)))
                    e = e.next;

                V oldValue = null;
                if (e != null) {
                    V v = e.value;
                    if (value == null || value.equals(v)) {
                        oldValue = v;
                        // All entries following removed node can stay
                        // in list, but all preceding ones need to be
                        // cloned.
                        ++modCount;
                        HashEntry newFirst = e.next;
                        for (HashEntry p = first; p != e; p = p.next)
                            newFirst = new HashEntry(p.key, p.hash,
                                                          newFirst, p.value);
                        tab[index] = newFirst;
                        count = c; // write-volatile
                    }
                }
                return oldValue;
            } finally {
                unlock();//釋放鎖
            }
        }

Count是被volatile所修飾,保證了count的可見性,避免操作數(shù)據(jù)的時(shí)候產(chǎn)生邏輯錯(cuò)誤。segment中的remove操作和HashMap大致一樣,HashMap沒有l(wèi)ock()和unlock()操作。

看下concurrentHashMap的get源碼

V get(Object key, int hash) {
            if (count != 0) { // read-volatile
                HashEntry e = getFirst(hash);
        //如果沒有找到則直接返回null
                while (e != null) {
                    if (e.hash == hash && key.equals(e.key)) {
            //由于沒有加鎖,在get的過程中,可能會(huì)有更新,拿到的key對(duì)應(yīng)的value可能為null,需要單獨(dú)判斷一遍
                        V v = e.value;
            //如果value為不為null,則返回獲取到的value
                        if (v != null)
                            return v;
                        return readValueUnderLock(e); // recheck
                    }
                    e = e.next;
                }
            }
            return null;
        }

關(guān)于concurrentHashMap的get的相關(guān)說明已經(jīng)在上面代碼中給出了注釋,這里就不多說了。

看下concurrentHashMap中的put

public V put(K key, V value) {
        if (value == null)
            throw new NullPointerException();
        int hash = hash(key.hashCode());
        return segmentFor(hash).put(key, hash, value, false);
}

可以看到concurrentHashMap不允許key或者value為null

接下來看下segment的put

V put(K key, int hash, V value, boolean onlyIfAbsent) {
            lock();
            try {
                int c = count;
                if (c++ > threshold) // ensure capacity
                    rehash();
                HashEntry[] tab = table;
                int index = hash & (tab.length - 1);
                HashEntry first = tab[index];
                HashEntry e = first;
                while (e != null && (e.hash != hash || !key.equals(e.key)))
                    e = e.next;

                V oldValue;
                if (e != null) {
                    oldValue = e.value;
                    if (!onlyIfAbsent)
                        e.value = value;
                }
                else {
                    oldValue = null;
                    ++modCount;
                    tab[index] = new HashEntry(key, hash, first, value);
                    count = c; // write-volatile
                }
                return oldValue;
            } finally {
                unlock();
            }
        }

 同樣也是加入了重入鎖,其他的基本和HashMap邏輯差不多。值得一提的是jdk8中添加的中的putval,這里就不多說了。

ConcurrentHashmap將數(shù)據(jù)結(jié)構(gòu)分為了多個(gè)Segment,也是使用重入鎖來解決高并發(fā),講他分為多個(gè)segment是為了減小鎖的力度,添加的時(shí)候加了鎖,索引的時(shí)候沒有加鎖,使用volatile修飾count是為了保持count的可見性,都是jdk為了解決并發(fā)和多線程操作的常用手段。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


網(wǎng)站欄目:如何淺析ConcurrentHashMap
文章URL:http://weahome.cn/article/ipgcde.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部