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

【Java】線程數(shù)據(jù)共享和安全 -ThreadLocal

這篇具有很好參考價值的文章主要介紹了【Java】線程數(shù)據(jù)共享和安全 -ThreadLocal。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

???歡迎來到@邊境矢夢°的csdn博文??

???本文主要梳理線程數(shù)據(jù)共享和安全 -ThreadLocal??


??我是邊境矢夢°,一個正在為秋招和算法競賽做準(zhǔn)備的學(xué)生??
??喜歡的朋友可以關(guān)注一下??????,下次更新不迷路??

Ps: 月亮越亮說明知識點越重要 (重要性或者難度越大)??????????????

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript

目錄

?? Java的有利武器:ThreadLocal?

?? 第一章 - 什么是ThreadLocal?

??第二章 - ThreadLocal原理

????源碼分析

?? 第三章 - 如何使用ThreadLocal

?? 第四章 - ThreadLocal的應(yīng)用場景

??總結(jié)


?? Java的有利武器:ThreadLocal ??

??今天我要為大家推薦一個Java中非常實用且神奇的工具——ThreadLocal。它可以讓我們在多線程環(huán)境下,輕松地實現(xiàn)線程私有的數(shù)據(jù)存儲。它可以幫助我們在多線程環(huán)境下輕松解決變量共享和線程安全的問題。??


?? 第一章 - 什么是ThreadLocal?

1. ThreadLocal 的作用,可以實現(xiàn)在同一個線程數(shù)據(jù)共享 , 從而解決多線程數(shù)據(jù)安全問題 .
2. ThreadLocal 可以給當(dāng)前線程關(guān)聯(lián)一個數(shù)據(jù) ( 普通變量、對象、數(shù)組 )set 方法 [ 源碼 !]
3. ThreadLocal 可以像 Map 一樣存取數(shù)據(jù), key 為當(dāng)前線程 , get 方法
4. 每一個 ThreadLocal 對象,只能為當(dāng)前線程關(guān)聯(lián)一個數(shù)據(jù),如果要為當(dāng)前線程關(guān)聯(lián)多個數(shù) 據(jù),就需要使用多個 ThreadLocal 對象實例
5. 每個 ThreadLocal 對象實例定義的時候,一般為 static 類型
6. ThreadLocal 中保存數(shù)據(jù),在線程銷毀后,會自動釋放

?? 圖一:ThreadLocal示意圖

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript


??第二章 - ThreadLocal原理

??一個ThreadLocal可以同時給多個線程分別關(guān)聯(lián)各自的數(shù)據(jù)。每個線程在訪問ThreadLocal時,都會獲取到自己獨立的數(shù)據(jù)副本,互不干擾。這就是ThreadLocal的獨立性和隔離性所表現(xiàn)出來的特點。

?? 圖二:ThreadLocal同時給多個線程分別關(guān)聯(lián)各自的數(shù)據(jù)示意圖

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript

??ThreadLocal是用于實現(xiàn)線程局部變量的機制,它為每個線程提供了一個獨立的副本,保證了線程的隔離性。因此,一個ThreadLocal變量最多只能關(guān)聯(lián)一個線程的數(shù)據(jù)。

?? 圖三:ThreadLocal一個線程一個數(shù)據(jù)示意圖

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript


????源碼分析

實際上,ThreadLocal本身并沒有存儲任何對象,所有的東西都存儲在Thread對象本身里!

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript

首先,在Thread對象(注意,不是ThreadLocal!)里有個成員變量:

ThreadLocal.ThreadLocalMap threadLocals = null;

這個成員變量的類型是ThreadLocal.ThreadLocalMap,這是ThreadLocal的一個內(nèi)部類,可以理解為一個簡單的HashMap(關(guān)于這個內(nèi)部類的實現(xiàn)本篇就不詳細展開了,有興趣的同學(xué)可以看源碼),就是保存鍵值對的一個容器。

其實,所有set到ThreadLocal上的對象,實際都保存在當(dāng)前Thread中的threadLocals成員變量里。

為了說的清楚,下面我用偽代碼的形式,寫一下ThreadLocal的Set()方法的核心邏輯:

public void set(T value) {
        Thread t = Thread.currentThread(); //先獲得當(dāng)前線程
        if (t.threadLocals != null){ //判斷當(dāng)前線程上的threadLocals成員是否為空
            t.threadLocals.set(this, value); //如果threadLocals不等于空,則set value,ThreadLocal對象作為key值。
        }else{
            t.threadLocals = new ThreadLocalMap(); //如果threadLocals為空,則創(chuàng)建之然后再set value。
            t.threadLocals.set(this, value); 
        }
    }

通過以上代碼大家應(yīng)該都能看清楚,真正的value值是保存在Thread對象上的,同時,key值是ThreadLocal對象。

再看看get方法,依然是只有核心邏輯的偽代碼:

public T get() {
        Thread t = Thread.currentThread(); //先獲得當(dāng)前線程
        if (t.threadLocals != null) { //判斷當(dāng)前線程上的threadLocals成員是否為空
            return (T)t.threadLocals.get(this); //不為空,則以ThreadLocal對象作為key值得到value,然后返回。
        }
        return setInitialValue(); //返回初始值
    }

理清了get和set方法,相信整個ThreadLocal的實現(xiàn)方式,大家應(yīng)該都比較清楚了。

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript

?來自簡書.?作者:我愛紐約先生的一段話(鏈接在文末)

作者之所以這樣設(shè)計,我相信是經(jīng)過了充分考慮的。我能想到的一點,就是考慮了對象的生命周期。

ThreadLocal要為每個線程維護value值,所以它的生命周期一般是長于線程對象生命周期的。一個長生命周期的對象維護一個短生命周期對象的引用,就有可能內(nèi)存泄露,除非開發(fā)者要手動remove掉。

而把value存放在Thread上,一切就可以完美的解決。因為這個value對象是專門為Thread對象而存在的,所以value對象和Thread對象的生命周期應(yīng)該完全一致。把value對象存放在Thread對象里,則不會有內(nèi)存泄露的風(fēng)險。雖然,Thread會維護一個ThreadLocal的引用(實際上是個弱引用),但是如前所說,一個短生命周期的對象維護長生命周期對象的引用,一般沒什么問題。

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript


?? 第三章 - 如何使用ThreadLocal

使用ThreadLocal非常簡單。我們只需創(chuàng)建一個ThreadLocal對象,并重寫initialValue()方法,定義每個線程初始的變量值。然后,通過調(diào)用get()方法可以獲取當(dāng)前線程的副本,而set()方法用于設(shè)置線程局部變量的值。

public class ThreadLocalExample {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            // 設(shè)置每個線程的初始值為0
            return 0;
        }
    };
    
    public static void main(String[] args) {
        // 創(chuàng)建3個線程執(zhí)行任務(wù)
        Thread t1 = new Thread(new MyRunnable());
        Thread t2 = new Thread(new MyRunnable());
        Thread t3 = new Thread(new MyRunnable());

        t1.start();
        t2.start();
        t3.start();

        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            int value = threadLocal.get();
            System.out.println("線程:" + Thread.currentThread().getName() + ",初始值:" + value);
            
            // 修改初始值
            value += 5;
            threadLocal.set(value);
            
            // 再次獲取修改后的值
            int updatedValue = threadLocal.get();
            System.out.println("線程:" + Thread.currentThread().getName() + ",修改后的值:" + updatedValue);
        }
    }
}

?在上述代碼中,我們創(chuàng)建了一個名為threadLocal的ThreadLocal對象,并重寫了它的initialValue()方法,用于定義每個線程初始的變量值(這里設(shè)置為0)。

然后,我們創(chuàng)建了3個線程,并在每個線程的run()方法中操作ThreadLocal對象。首先,通過get()方法獲取當(dāng)前線程的副本,并輸出初始值。然后,我們使用set()方法修改初始值,并再次使用get()方法獲取修改后的值。

運行這段代碼,你會看到每個線程都有自己獨立的初始值和修改后的值。這表明每個線程通過ThreadLocal對象進行了數(shù)據(jù)隔離,互不干擾。

你可以根據(jù)自己的需求來定義ThreadLocal對象的值和操作邏輯。


?? 第四章 - ThreadLocal的應(yīng)用場景

ThreadLocal的應(yīng)用非常廣泛,下面為大家介紹幾個特別實用的場景:

1?? 數(shù)據(jù)庫連接管理:在多線程環(huán)境下,使用ThreadLocal可以方便地管理數(shù)據(jù)庫連接,每個線程都能獲取到自己獨立的連接副本,避免了線程安全和資源競爭問題。

2?? Web應(yīng)用用戶信息存儲:對于一個Web應(yīng)用程序,可以使用ThreadLocal將當(dāng)前用戶的登錄信息存儲在線程局部變量中,這樣在后續(xù)的請求處理過程中就無需傳遞這些信息了。

3?? 日志跟蹤:ThreadLocal還可以用于日志跟蹤,每個線程都有自己的日志副本,方便調(diào)試和定位問題。


??總結(jié)

??Thread里面存儲著各自的ThreadLocalMap, 并且Thread的每一個ThreadLocal會根據(jù)Thread的生命周期進行銷毀, 每個ThreadLocalMap都屬于某一個Thread, 而ThreadLocal只是ThreadLocalMap里面的一個而已, ThreadLocal對象實例就是Map中的鍵, 根據(jù)它就可以得到value, 一個ThreadLocal只能為一個Thread服務(wù)一個數(shù)據(jù), 但是同時可以為其他Thread服務(wù).

??為什么是一個ThreadLocal給Thread關(guān)聯(lián)一個數(shù)據(jù)呢?

因為set()方法中,?t.threadLocals.set(this, value); //如果threadLocals不等于空,則set value,ThreadLocal對象作為key值。

不管你怎么弄都是一個ThreadLocal對應(yīng)著一個相應(yīng)的Thread的

?? 圖四:ThreadLocal原理圖

threadlocal線程共享,Java,java,開發(fā)語言,ThreadLocal,servlet,tomcat,javascript

?? 精彩的ThreadLocal世界就在眼前!無論你是面對高并發(fā)的系統(tǒng),還是只是想學(xué)習(xí)Java多線程編程,ThreadLocal都能幫助你輕松解決問題。希望這篇推薦能給你帶來靈感與啟發(fā)。如果你有其他關(guān)于ThreadLocal的經(jīng)驗和想法,也歡迎在評論區(qū)與我分享。下次再見!??

??????以下是對我?guī)椭芏嗟奈恼?

ThreadLocal到底是個什么東西? - 簡書 (jianshu.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-696450.html

到了這里,關(guān)于【Java】線程數(shù)據(jù)共享和安全 -ThreadLocal的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • idea Springboot 高??蒲匈Y源共享系統(tǒng)VS開發(fā)mysql數(shù)據(jù)庫web結(jié)構(gòu)java編程計算機網(wǎng)頁源碼maven項目

    idea Springboot 高??蒲匈Y源共享系統(tǒng)VS開發(fā)mysql數(shù)據(jù)庫web結(jié)構(gòu)java編程計算機網(wǎng)頁源碼maven項目

    一、源碼特點 ? springboot 高校科研資源共享系統(tǒng)是一套完善的信息系統(tǒng),結(jié)合springboot框架和bootstrap完成本系統(tǒng),對理解JSP java編程開發(fā)語言有幫助系統(tǒng)采用springboot框架(MVC模式開發(fā)), 系統(tǒng)具有完整的源代碼和數(shù)據(jù)庫,系統(tǒng)主要采用B/S模式開發(fā)。 springboot 高??蒲匈Y源共享

    2024年02月07日
    瀏覽(34)
  • Java多線程之線程安全問題

    Java多線程之線程安全問題

    我們知道操作系統(tǒng)中線程程的調(diào)度是搶占式執(zhí)行的, 宏觀上上的感知是隨機的, 這就導(dǎo)致了多線程在進行線程調(diào)度時線程的執(zhí)行順序是不確定的, 因此多線程情況下的代碼的執(zhí)行順序可能就會有無數(shù)種, 我們需要保證這無數(shù)種線程調(diào)度順序的情況下, 代碼的執(zhí)行結(jié)果都是正確的

    2023年04月17日
    瀏覽(19)
  • Java 多線程之線程安全集合

    Java 多線程之線程安全集合

    集合關(guān)系圖 本文主要關(guān)注線程安全的集合,如 List、Set、Queue、Map 等接口的線程安全的實現(xiàn)方式,有關(guān)集合基礎(chǔ)知識請轉(zhuǎn)到這里。所謂線程安全集合,就是在多線程環(huán)境中使用集合不會導(dǎo)致數(shù)據(jù)不一致和數(shù)據(jù)異常的集合。在 Java 中線程安全集現(xiàn)在基本都使用 java.util.concurrent

    2024年02月05日
    瀏覽(44)
  • java基礎(chǔ)之線程安全問題以及線程安全集合類

    當(dāng)多個線程同時訪問同一個臨界資源時,原子操作可能被破壞,會導(dǎo)致數(shù)據(jù)丟失, 就會觸發(fā)線程安全問題 臨界資源: 被多個線程同時訪問的對象 原子操作: 線程訪問臨界資源的過程中不可更改和缺失的操作 互斥鎖 每個對象都默認擁有互斥鎖, 該鎖默認不開啟. 當(dāng)開啟互斥鎖之后

    2024年01月18日
    瀏覽(66)
  • 【javaEE面試題(四)線程不安全的原因】【1. 修改共享數(shù)據(jù) 2. 操作不是原子性 3. 內(nèi)存可見性 4. 代碼順序性】

    【javaEE面試題(四)線程不安全的原因】【1. 修改共享數(shù)據(jù) 2. 操作不是原子性 3. 內(nèi)存可見性 4. 代碼順序性】

    大家觀察下是否適用多線程的現(xiàn)象是否一致?同時嘗試思考下為什么會有這樣的現(xiàn)象發(fā)生呢? 原因是 1.load 2. add 3. save 注意:可能會導(dǎo)致 小于5w 想給出一個線程安全的確切定義是復(fù)雜的,但我們可以這樣認為: 如果多線程環(huán)境下代碼運行的結(jié)果是符合我們預(yù)期的,即在單線

    2024年02月13日
    瀏覽(45)
  • java多線程之線程安全(重點,難點)

    java多線程之線程安全(重點,難點)

    由于操作系統(tǒng)中,線程的調(diào)度是搶占式執(zhí)行的,或者說是隨機的,這就造成線程調(diào)度執(zhí)行時,線程的執(zhí)行順序是不確定的,雖然有一些代碼在這種執(zhí)行順序不同的情況下也不會運行出錯,但是還有一部分代碼會因為執(zhí)行順序發(fā)生改變而受到影響,這就會造成程序出現(xiàn)Bug,對于多線程并發(fā)

    2024年01月25日
    瀏覽(28)
  • Java中的多線程——線程安全問題

    Java中的多線程——線程安全問題

    作者:~小明學(xué)編程 ? 文章專欄:JavaEE 格言:熱愛編程的,終將被編程所厚愛。 目錄 多線程所帶來的不安全問題 什么是線程安全 線程不安全的原因 修改共享數(shù)據(jù) 修改操作不是原子的 內(nèi)存可見性對線程的影響 指令重排序 解決線程不安全的問題 synchronized 互斥 刷新內(nèi)

    2024年02月03日
    瀏覽(22)
  • 【Java】Java中線程安全有哪些實現(xiàn)思路?

    【Java】Java中線程安全有哪些實現(xiàn)思路?

    在 Java 多線程編程中,線程安全是一個非常重要的概念。 線程安全通常指程序在多線程并發(fā)執(zhí)行時,仍然能夠保持正確的行為。 Java 提供了很多實現(xiàn)線程安全的方法,本文將介紹幾種常見的實現(xiàn)思路。 synchronized 是 Java 中最基本的解決線程安全問題的方法,它可以確保

    2024年02月04日
    瀏覽(28)
  • 【Java系列】詳解多線程(三)—— 線程安全(下篇)

    【Java系列】詳解多線程(三)—— 線程安全(下篇)

    個人主頁:兜里有顆棉花糖 歡迎 點贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng) 收錄于專欄【Java系列專欄】【JaveEE學(xué)習(xí)專欄】 本專欄旨在分享學(xué)習(xí)Java的一點學(xué)習(xí)心得,歡迎大家在評論區(qū)交流討論?? 我們先來看一下什么是內(nèi)存可見性問題,通過一段代碼來進

    2024年02月04日
    瀏覽(28)
  • 【Java】線程安全問題

    【Java】線程安全問題

    在之前的文章中,已經(jīng)介紹了關(guān)于線程的基礎(chǔ)知識。 我的主頁: ??????愛吃南瓜的北瓜 歡迎各位大佬來到我的主頁進行指點 一同進步?。?! 我們創(chuàng)建兩個線程t1和t2,對靜態(tài)變量count執(zhí)行++操作各50000次。 我們的預(yù)期結(jié)果是100000。但是當(dāng)兩個線程分別執(zhí)行++操作時最后的結(jié)果

    2024年04月10日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包