国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java-多線程-深入理解ConcurrentHashMap

這篇具有很好參考價(jià)值的文章主要介紹了Java-多線程-深入理解ConcurrentHashMap。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

什么是ConcurrentHashMap?

????ConcurrentHashMap(Concurrent:并存的,同時(shí)發(fā)生的;)
????ConcurrentHashMap是Java中的一個(gè)線程安全的哈希表實(shí)現(xiàn),它可以在多線程環(huán)境下高效地進(jìn)行并發(fā)操作。

為什么有ConcurrentHashMap?

????HashMap線程不安全,在多線程操作下可能會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)亂

和HashMap區(qū)別

Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

示例代碼對(duì)比

????使用HashMap和ConcurrentHashMap分別實(shí)現(xiàn)以下需求。
????????用30個(gè)線程向?qū)嵗龅膍ap中插入key,value。每一次插入后,把map打印出來(lái)(for循環(huán)中sout)
????????key為for循環(huán)中的i值
????????value:使用UUID

public class HashMapUnsafeTest {
    public static void main(String[] args) throws InterruptedException {
        //演示HashMap
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < 30; i++) {
            String key = String.valueOf(i);
            new Thread(() -> {
                //向集合添加內(nèi)容
                map.put(key, UUID.randomUUID().toString().substring(0, 8));
                //從集合中獲取內(nèi)容
                System.out.println(map);
            }, "").start();
        }
    }
}
public class ConcurrentHashMapSafe {
    public static void main(String[] args) throws InterruptedException {

        //演示ConcurrentHashMap
        Map<String, String> map = new ConcurrentHashMap<>();
        for (int i = 0; i < 30; i++) {
            String key = String.valueOf(i);
            new Thread(() -> {
                //向集合添加內(nèi)容
                map.put(key, UUID.randomUUID().toString().substring(0, 8));
                //從集合中獲取內(nèi)容
                System.out.println(map);
            }, "").start();

        }
    }
}

????多個(gè)線程同時(shí)對(duì)同一個(gè)集合進(jìn)行增刪操作導(dǎo)致錯(cuò)誤

Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

JDK7和JDK8中ConcurrentHashMap整體架構(gòu)的區(qū)別

JDK7中

Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

JDK8中

Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

使用到的數(shù)據(jù)結(jié)構(gòu):數(shù)組、單向鏈表、紅黑樹
Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

其中涉及到幾個(gè)核心的參數(shù)

// 最大容量,2^30
private static final int MAXIMUM_CAPACITY = 1 << 30;
// 默認(rèn)長(zhǎng)度
private static final int DEFAULT_CAPACITY = 16;


//遺留問(wèn)題:為什么樹化條件是8而取消樹化條件卻是6呢?
// 鏈表樹化條件-是根據(jù)線程競(jìng)爭(zhēng)情況和紅黑樹的操作成本進(jìn)行設(shè)計(jì)的。
static final int TREEIFY_THRESHOLD = 8;
// 取消樹化條件-為了避免過(guò)度的樹化,防止內(nèi)存占用過(guò)高。
static final int UNTREEIFY_THRESHOLD = 6;              //鏈表結(jié)構(gòu)中,每個(gè)節(jié)點(diǎn)只需要存儲(chǔ)指向下一個(gè)節(jié)點(diǎn)的指針,而不需要存儲(chǔ)節(jié)點(diǎn)的值。因此,鏈表只需要存儲(chǔ)節(jié)點(diǎn)的引用,占用較少的內(nèi)存空間。樹結(jié)構(gòu)中每個(gè)節(jié)點(diǎn)需要存儲(chǔ)節(jié)點(diǎn)的值以及指向子節(jié)點(diǎn)的指針。

????核心為Hash表,存在Hash沖突問(wèn)題
????使用鏈?zhǔn)酱鎯?chǔ)方式解決沖突,沖突較多時(shí),導(dǎo)致鏈表過(guò)長(zhǎng),查詢效率較低,在JDK1.8中引入紅黑樹機(jī)制;
????當(dāng)數(shù)組長(zhǎng)度大于64,且鏈表長(zhǎng)度大于等于8時(shí),單項(xiàng)鏈表轉(zhuǎn)為紅黑樹
????當(dāng)鏈表長(zhǎng)度小于6時(shí),紅黑樹會(huì)退化為單向鏈表

ConcurrentHashMap的基本功能

????本質(zhì)上是一個(gè)HashMap,功能和HashMap是一樣的
????但ConcurrentHashMap在HashMap基礎(chǔ)上提供了并發(fā)安全的實(shí)現(xiàn),主要通過(guò)對(duì)node節(jié)點(diǎn)加鎖實(shí)現(xiàn),來(lái)保證對(duì)數(shù)據(jù)更新的安全性
鎖粒度變小
Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

在性能方面的優(yōu)化

????在JDK1.8中鎖的粒度是數(shù)組中的某一個(gè)節(jié)點(diǎn),在JDK1.7中鎖定的是一個(gè)Segment,鎖的范圍更大
????保證線程安全機(jī)制:
????????JDK7采用segment的分段鎖機(jī)制實(shí)現(xiàn)線程安全,其中segment繼承自ReentrantLock。
????????JDK8采用CAS(讀)+Synchronized(寫)保證線程安全。

????鎖的粒度:原來(lái)是對(duì)需要進(jìn)行數(shù)據(jù)操作的Segment加鎖,JDK8調(diào)整為對(duì)每個(gè)數(shù)組元素加鎖(Node)。

????鏈表轉(zhuǎn)化為紅黑樹:定位結(jié)點(diǎn)的hash算法簡(jiǎn)化會(huì)帶來(lái)弊端,Hash沖突加劇,因此在鏈表節(jié)點(diǎn)數(shù)量大于8時(shí),會(huì)將鏈表轉(zhuǎn)化為紅黑樹進(jìn)行存儲(chǔ)。

使用到的技術(shù)-CAS

概念說(shuō)明

CAS的全稱是:比較并交換(Compare And Swap)。在CAS中,有這樣三個(gè)值:
????V:要更新的變量(var)
????E:預(yù)期值(expected)
????N:新值(new)

比較并交換的過(guò)程如下:

????判斷V是否等于E,如果等于,將V的值設(shè)置為N;如果不等,說(shuō)明已經(jīng)有其它線程更新了V,則當(dāng)前線程放棄更新,什么都不做。
Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

舉例說(shuō)明

????如果有一個(gè)多個(gè)線程共享的變量i原本等于5,我現(xiàn)在在線程A中,想把它設(shè)置為新的值6;
我們使用CAS來(lái)做這個(gè)事情;
????首先我們用i去與5對(duì)比,發(fā)現(xiàn)它等于5,說(shuō)明沒(méi)有被其它線程改過(guò),那我就把它設(shè)置為新的值6,此次CAS成功,i的值被設(shè)置成了6;
????如果不等于5,說(shuō)明i被其它線程改過(guò)了(比如現(xiàn)在i的值為2),那么我就什么也不做,此次CAS失敗,i的值仍然為2。

底層原理

????unsafe類——以下是類中涉及到的三個(gè)方法用來(lái)實(shí)現(xiàn)CAS效果的,這三個(gè)方法都是由native進(jìn)行修飾的。具體的實(shí)現(xiàn)是由C++寫的。
Java-多線程-深入理解ConcurrentHashMap,# java相關(guān),java,開發(fā)語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)

代碼演示

沒(méi)有使用CAS的代碼

package com.example.threadpool.CAS;



public class NoCASDemo {

    private static int counter = 0;

    public static void main(String[] args) throws InterruptedException {
        //線程一
        Thread thread1= new Thread(() -> {
            for (int i=0; i<10000;i++){
                counter++;
            }
        });
        //線程二
        Thread thread2= new Thread(() -> {
            for (int i=0; i<10000;i++){
                counter++;
            }
        });
        //執(zhí)行線程
        thread1.start();
        thread2.start();
        //等待執(zhí)行完線程1和2
        thread1.join();
        thread2.join();

        System.out.println("查看counter的總數(shù)"+counter);
    }

}

使用CAS的代碼

package com.example.threadpool.CAS;

import java.util.concurrent.atomic.AtomicInteger;



public class CASDemo {

    private static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        //線程一
        Thread thread1= new Thread(() -> {
            for (int i=0; i<10000;i++){
                increment();
            }
        });
        //線程二
        Thread thread2= new Thread(() -> {
            for (int i=0; i<10000;i++){
                increment();
            }
        });
        //執(zhí)行線程
        thread1.start();
        thread2.start();
        //等待執(zhí)行完線程1和2
        thread1.join();
        thread2.join();

        System.out.println("查看counter的總數(shù)"+counter.get());
    }

    public static void increment() {
        int currentValue;
        int newValue;
        do {
            //獲取counter對(duì)象的value值
            currentValue = counter.get();
            //將counter對(duì)象的value值加1
            newValue = currentValue + 1;

        } while (!counter.compareAndSet(currentValue, newValue));
    }

}

總結(jié)

????總的來(lái)說(shuō),ConcurrentHashMap是Java中線程安全的哈希表實(shí)現(xiàn),它通過(guò)使用鎖分段技術(shù)來(lái)提供高效的并發(fā)性能。相比于Hashtable,ConcurrentHashMap在多線程環(huán)境下能夠更好地支持高并發(fā)讀寫操作。

????使用ConcurrentHashMap可以在多線程環(huán)境下安全地進(jìn)行數(shù)據(jù)操作,而無(wú)需手動(dòng)加鎖。它通過(guò)將整個(gè)數(shù)據(jù)結(jié)構(gòu)分成多個(gè)段來(lái)實(shí)現(xiàn)并發(fā)性能的提升,不同的線程可以同時(shí)訪問(wèn)不同的段,從而減少了線程之間的競(jìng)爭(zhēng)。

????ConcurrentHashMap的設(shè)計(jì)考慮了線程安全和性能的平衡。它提供了一些有用的方法,如putIfAbsent()、replace()等,可以方便地進(jìn)行原子性的操作。此外,ConcurrentHashMap還支持遍歷操作,可以通過(guò)迭代器安全地遍歷其中的元素。

????需要注意的是,雖然ConcurrentHashMap是線程安全的,但并不保證對(duì)于單個(gè)操作的原子性。如果需要進(jìn)行復(fù)合操作,仍然需要額外的同步措施。

????總的來(lái)說(shuō),ConcurrentHashMap是一個(gè)強(qiáng)大的線程安全的哈希表實(shí)現(xiàn),適用于多線程環(huán)境下的高并發(fā)讀寫操作。它提供了高效的并發(fā)性能,可以提升系統(tǒng)的吞吐量和響應(yīng)速度。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-632881.html

到了這里,關(guān)于Java-多線程-深入理解ConcurrentHashMap的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【多線程系列-03】深入理解java中線程的生命周期,任務(wù)調(diào)度

    【多線程系列-03】深入理解java中線程的生命周期,任務(wù)調(diào)度

    多線程系列整體欄目 內(nèi)容 鏈接地址 【一】深入理解進(jìn)程、線程和CPU之間的關(guān)系 https://blog.csdn.net/zhenghuishengq/article/details/131714191 【二】java創(chuàng)建線程的方式到底有幾種?(詳解) https://blog.csdn.net/zhenghuishengq/article/details/127968166 【三】深入理解java中線程的生命周期,任務(wù)調(diào)度 ht

    2024年02月17日
    瀏覽(28)
  • 深入理解 Java 多線程、Lambda 表達(dá)式及線程安全最佳實(shí)踐

    線程使程序能夠通過(guò)同時(shí)執(zhí)行多個(gè)任務(wù)而更有效地運(yùn)行。 線程可用于在不中斷主程序的情況下在后臺(tái)執(zhí)行復(fù)雜的任務(wù)。 創(chuàng)建線程 有兩種創(chuàng)建線程的方式。 擴(kuò)展Thread類 可以通過(guò)擴(kuò)展Thread類并覆蓋其run()方法來(lái)創(chuàng)建線程: 實(shí)現(xiàn)Runnable接口 另一種創(chuàng)建線程的方式是實(shí)現(xiàn)Runnable接口

    2024年03月15日
    瀏覽(29)
  • 深入理解Java線程池ThreadPoolExcutor實(shí)現(xiàn)原理、數(shù)據(jù)結(jié)構(gòu)和算法(源碼解析)

    深入理解Java線程池ThreadPoolExcutor實(shí)現(xiàn)原理、數(shù)據(jù)結(jié)構(gòu)和算法(源碼解析)

    什么是線程池? ????????線程池主要是為了解決執(zhí)行新任務(wù)執(zhí)行時(shí),應(yīng)用程序?yàn)闇p少為任務(wù)創(chuàng)建一個(gè)新線程和任務(wù)執(zhí)行完畢時(shí)銷毀線程所帶來(lái)的開銷。通過(guò)線程池,可以在項(xiàng)目初始化時(shí)就創(chuàng)建一個(gè)線程集合,然后在需要執(zhí)行新任務(wù)時(shí)重用這些線程而不是每次都新建一個(gè)線

    2024年02月07日
    瀏覽(41)
  • 華為云出品《深入理解高并發(fā)編程:Java線程池核心技術(shù)》電子書發(fā)布

    華為云出品《深入理解高并發(fā)編程:Java線程池核心技術(shù)》電子書發(fā)布

    系統(tǒng)拆解線程池核心源碼的開源小冊(cè) 透過(guò)源碼看清線程池背后的設(shè)計(jì)和思路 詳細(xì)解析AQS并發(fā)工具類 點(diǎn)擊下方鏈接進(jìn)入官網(wǎng),右上角搜索框搜索“《深入理解高并發(fā)編程:Java線程池核心技術(shù)》” 即可獲取下載。 https://auth.huaweicloud.com/authui/login.html?locale=zh-cnservice=https%3A%2F%2F

    2024年02月16日
    瀏覽(41)
  • Java進(jìn)階(ConcurrentHashMap)——面試時(shí)ConcurrentHashMap常見問(wèn)題解讀 & 結(jié)合源碼分析 & 多線程CAS比較并交換 初識(shí)

    Java進(jìn)階(ConcurrentHashMap)——面試時(shí)ConcurrentHashMap常見問(wèn)題解讀 & 結(jié)合源碼分析 & 多線程CAS比較并交換 初識(shí)

    List、Set、HashMap作為Java中常用的集合,需要深入認(rèn)識(shí)其原理和特性。 本篇博客介紹常見的關(guān)于Java中線程安全的ConcurrentHashMap集合的面試問(wèn)題,結(jié)合源碼分析題目背后的知識(shí)點(diǎn)。 關(guān)于List的博客文章如下: Java進(jìn)階(List)——面試時(shí)List常見問(wèn)題解讀 結(jié)合源碼分析 關(guān)于的Set的博

    2024年02月06日
    瀏覽(21)
  • 大聰明教你學(xué)Java | 深入淺出聊 ConcurrentHashMap

    ??作者簡(jiǎn)介: 不肯過(guò)江東丶,一個(gè)來(lái)自二線城市的程序員,致力于用“猥瑣”辦法解決繁瑣問(wèn)題,讓復(fù)雜的問(wèn)題變得通俗易懂。 ??支持作者: 點(diǎn)贊??、關(guān)注??、留言??~ 在 Java 的集合框架中,HashMap 是一種非常常用的數(shù)據(jù)結(jié)構(gòu),它提供了鍵值對(duì)形式的存儲(chǔ)和訪問(wèn)方式。然

    2024年02月10日
    瀏覽(23)
  • 深入理解多線程編程

    深入理解多線程編程

    title: 深入理解多線程編程 date: 2024/4/25 17:32:02 updated: 2024/4/25 17:32:02 categories: 后端開發(fā) tags: 線程同步 互斥鎖 死鎖避免 競(jìng)態(tài)條件 線程池 異步編程 性能優(yōu)化 線程 :在操作系統(tǒng)中,一個(gè)程序可以被劃分為多個(gè)執(zhí)行流,每個(gè)執(zhí)行流就是一個(gè)獨(dú)立的線程。線程是進(jìn)程中的一個(gè)執(zhí)行實(shí)

    2024年04月25日
    瀏覽(23)
  • 深入理解MySQL InnoDB線程模型

    當(dāng)我們談?wù)摂?shù)據(jù)庫(kù)性能時(shí),存儲(chǔ)引擎的線程模型是一個(gè)不可忽視的方面。MySQL的InnoDB存儲(chǔ)引擎,作為目前最受歡迎的存儲(chǔ)引擎之一,其線程模型的設(shè)計(jì)對(duì)于實(shí)現(xiàn)高并發(fā)、高性能的數(shù)據(jù)操作至關(guān)重要。在本文中,我們將深入探討MySQL InnoDB線程模型的工作原理和關(guān)鍵組件。 在Inn

    2024年01月25日
    瀏覽(16)
  • 深入理解Flink Mailbox線程模型

    Mailbox線程模型通過(guò)引入阻塞隊(duì)列配合一個(gè)Mailbox線程的方式,可以輕松修改StreamTask內(nèi)部狀態(tài)的修改。Checkpoint、ProcessingTime Timer的相關(guān)操作(Runnable任務(wù)),會(huì)以Mail的形式保存到Mailbox內(nèi)的阻塞隊(duì)列中。StreamTask在invoke階段的runMailboxLoop時(shí)期,就會(huì)輪詢Mailbox來(lái)處理隊(duì)列中保存的M

    2024年02月12日
    瀏覽(21)
  • 深入理解高并發(fā)編程 - 線程的執(zhí)行順序

    在Java中,線程的執(zhí)行順序是由操作系統(tǒng)的調(diào)度機(jī)制決定的,具體順序是不確定的,取決于多個(gè)因素,如操作系統(tǒng)的調(diào)度策略、線程的優(yōu)先級(jí)、線程的狀態(tài)轉(zhuǎn)換等。因此,不能對(duì)線程的執(zhí)行順序做出可靠的假設(shè)。 以下是一個(gè)簡(jiǎn)單的Java代碼示例,演示了多個(gè)線程的執(zhí)行順序是不

    2024年02月14日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包