亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java ThreadLocal線程局部變量常用方法使用場(chǎng)景示例詳解

 更新時(shí)間:2023年07月19日 08:53:15   作者:今夜有點(diǎn)兒涼  
這篇文章主要介紹了為大家java ThreadLocal線程局部變量常用方法使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

java ThreadLocal線程局部變量常用方法使用場(chǎng)景示例詳解

1. 什么是 ThreadLocal ?

ThreadLocal 是 Java 中的一個(gè)類,用于在多線程環(huán)境下為每個(gè)線程提供獨(dú)立的變量副本。它可以解決多線程并發(fā)訪問共享變量時(shí)的線程安全問題。

在多線程應(yīng)用程序中,多個(gè)線程可能同時(shí)訪問同一個(gè)變量,如果沒有適當(dāng)?shù)耐綑C(jī)制,就會(huì)導(dǎo)致數(shù)據(jù)的不一致性和競(jìng)態(tài)條件。ThreadLocal 提供了一種線程級(jí)別的變量隔離機(jī)制,使得每個(gè)線程都擁有自己獨(dú)立的變量副本,互不干擾。

2. ThreadLocal 類提供了以下常用方法:

  • get():獲取當(dāng)前線程的 ThreadLocal 變量的值。如果變量尚未被當(dāng)前線程設(shè)置,則返回 null。
  • set(T value):設(shè)置當(dāng)前線程的 ThreadLocal 變量的值為指定的值。
  • remove():移除當(dāng)前線程的 ThreadLocal 變量。清除后,下次調(diào)用 get() 方法將返回 null。
  • initialValue():返回 ThreadLocal 的初始值??梢酝ㄟ^繼承 ThreadLocal 并覆蓋該方法來自定義初始值。
  • withInitial(Supplier<? extends T> supplier):使用指定的 Supplier 函數(shù)式接口提供的初始值創(chuàng)建一個(gè) ThreadLocal 實(shí)例。

ThreadLocal 的這些方法提供了對(duì)線程局部變量的管理和訪問。你可以使用 get() 和 set() 方法在當(dāng)前線程中存儲(chǔ)和獲取變量的值,使用 remove() 方法清除變量,使用 initialValue() 方法自定義初始值,以及使用 withInitial() 方法創(chuàng)建具有自定義初始值的 ThreadLocal 實(shí)例。

3. ThreadLocal 使用案例:

以下是一些使用 ThreadLocal 的案例:

線程安全的計(jì)數(shù)器:

public class ThreadSafeCounter {
    private static ThreadLocal<Integer> counter = ThreadLocal.withInitial(() -> 0);
    public static void increment() {
        counter.set(counter.get() + 1);
    }
    public static int getCount() {
        return counter.get();
    }
}

在多線程環(huán)境下,每個(gè)線程可以通過 increment() 方法增加計(jì)數(shù)器的值,而不會(huì)與其他線程的計(jì)數(shù)器產(chǎn)生沖突。每個(gè)線程訪問的是自己獨(dú)立的計(jì)數(shù)器副本。

線程上下文傳遞:

public class UserContext {
    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();
    public static void setUser(User user) {
        userThreadLocal.set(user);
    }
    public static User getUser() {
        return userThreadLocal.get();
    }
}

在一個(gè) Web 應(yīng)用中,可以使用 ThreadLocal 存儲(chǔ)當(dāng)前請(qǐng)求的用戶信息,方便在不同層次的代碼中訪問。在請(qǐng)求處理的開始階段,將用戶信息設(shè)置到 ThreadLocal 中,然后在后續(xù)的代碼中可以通過 getUser() 方法獲取用戶信息。

數(shù)據(jù)庫連接管理:

public class DBConnectionManager {
    private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
    public static void openConnection() {
        // 獲取數(shù)據(jù)庫連接并設(shè)置到 ThreadLocal
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "password");
        connectionThreadLocal.set(connection);
    }
    public static Connection getConnection() {
        return connectionThreadLocal.get();
    }
    public static void closeConnection() {
        // 關(guān)閉數(shù)據(jù)庫連接
        Connection connection = connectionThreadLocal.get();
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // 異常處理
            }
        }
        // 清理 ThreadLocal 變量
        connectionThreadLocal.remove();
    }
}

在多線程的數(shù)據(jù)庫訪問場(chǎng)景中,可以使用 ThreadLocal 管理數(shù)據(jù)庫連接。每個(gè)線程都可以通過 getConnection() 方法獲取自己獨(dú)立的數(shù)據(jù)庫連接,而不會(huì)與其他線程的連接產(chǎn)生沖突。在連接使用完畢后,需要顯式地調(diào)用 closeConnection() 方法關(guān)閉連接并清理 ThreadLocal 變量。

日期時(shí)間格式化:

public class DateFormatter {
    private static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    public static String format(Date date) {
        return dateFormatThreadLocal.get().format(date);
    }
}

在多線程環(huán)境下,使用 SimpleDateFormat 進(jìn)行日期時(shí)間格式化可能會(huì)引發(fā)線程安全問題。通過為每個(gè)線程創(chuàng)建獨(dú)立的 SimpleDateFormat 實(shí)例,并使用 ThreadLocal 進(jìn)行存儲(chǔ)和獲取,可以避免線程安全問題。每個(gè)線程訪問的是自己獨(dú)立的 SimpleDateFormat 實(shí)例。

這些案例展示了 ThreadLocal 的使用方式,通過為每個(gè)線程提供獨(dú)立的變量副本,實(shí)現(xiàn)了數(shù)據(jù)的隔離和線程安全。需要根據(jù)具體的需求和場(chǎng)景選擇是否使用 ThreadLocal。

4. ThreadLocal 和 加鎖 有什么區(qū)別?

ThreadLocal 和加鎖是兩種不同的機(jī)制,用于解決多線程環(huán)境下的線程安全問題,但它們的作用和使用方式有所不同。

  • ThreadLocal:

    • 作用:ThreadLocal 提供了一種線程局部變量的機(jī)制,使得每個(gè)線程都可以獨(dú)立地?fù)碛凶约旱淖兞扛北荆瑥亩鴮?shí)現(xiàn)了數(shù)據(jù)的隔離。
    • 使用方式:每個(gè)線程通過 ThreadLocal 對(duì)象獲取和設(shè)置自己獨(dú)立的變量副本,不會(huì)與其他線程的變量產(chǎn)生沖突。每個(gè)線程都可以獨(dú)立地修改自己的副本,而不需要加鎖。
    • 適用場(chǎng)景:適用于多線程環(huán)境下,每個(gè)線程需要獨(dú)立地?fù)碛凶约旱淖兞扛北?,避免線程之間的數(shù)據(jù)共享和競(jìng)爭(zhēng)。
  • 加鎖:

    • 作用:加鎖是一種同步機(jī)制,用于控制多個(gè)線程對(duì)共享資源的訪問,以保證線程安全性。
    • 使用方式:通過在關(guān)鍵代碼段或方法中加鎖,確保同一時(shí)間只有一個(gè)線程能夠執(zhí)行該代碼段或方法,其他線程需要等待鎖的釋放。
    • 適用場(chǎng)景:適用于多線程環(huán)境下,多個(gè)線程需要同時(shí)訪問共享資源,并且需要保證操作的原子性和線程安全性。

區(qū)別:

  • ThreadLocal 是通過為每個(gè)線程提供獨(dú)立的變量副本來實(shí)現(xiàn)數(shù)據(jù)隔離,不需要加鎖。每個(gè)線程都可以獨(dú)立地修改自己的變量副本,不會(huì)影響其他線程的副本。
  • 加鎖是通過同步機(jī)制來保證多個(gè)線程對(duì)共享資源的訪問的互斥性。只有持有鎖的線程能夠執(zhí)行關(guān)鍵代碼段或方法,其他線程需要等待鎖的釋放。
  • ThreadLocal 適用于需要在線程之間隔離數(shù)據(jù)的場(chǎng)景,而加鎖適用于多個(gè)線程需要同時(shí)訪問共享資源的場(chǎng)景。
  • 使用 ThreadLocal 可以避免鎖競(jìng)爭(zhēng)和線程阻塞,但需要注意內(nèi)存管理和清理 ThreadLocal 變量的問題。而加鎖會(huì)引入線程阻塞和上下文切換的開銷。

綜上所述,ThreadLocal 和加鎖是兩種不同的機(jī)制,用于解決多線程環(huán)境下的線程安全問題,具有不同的作用和使用方式。選擇使用哪種機(jī)制取決于具體的場(chǎng)景和需求。

5. Thread,ThreadLocal,ThreadLocalMap 他們之間的關(guān)系?

Thread、ThreadLocal 和 ThreadLocalMap 是 Java 多線程編程中的三個(gè)關(guān)鍵概念,它們之間有著密切的關(guān)系。

  • Thread(線程):Thread 是 Java 中用于創(chuàng)建和管理線程的類。每個(gè)線程都有自己的執(zhí)行上下文和棧,可以獨(dú)立地執(zhí)行代碼。Thread 類提供了一組方法用于線程的創(chuàng)建、啟動(dòng)、暫停、恢復(fù)、終止等操作。
  • ThreadLocal(線程局部變量):ThreadLocal 是 Java 中的一個(gè)類,用于在每個(gè)線程中存儲(chǔ)和獲取變量的值。它提供了一種線程級(jí)別的數(shù)據(jù)隔離機(jī)制,使得每個(gè)線程都可以擁有自己的變量副本,不會(huì)與其他線程的變量產(chǎn)生沖突。ThreadLocal 類提供了一組方法用于操作線程局部變量,例如設(shè)置變量值、獲取變量值、刪除變量等。
  • ThreadLocalMap(線程局部變量映射):ThreadLocalMap 是 ThreadLocal 類中的一個(gè)內(nèi)部類,用于實(shí)際存儲(chǔ)線程局部變量的映射表。每個(gè) ThreadLocal 實(shí)例都有一個(gè)對(duì)應(yīng)的 ThreadLocalMap 對(duì)象,用于存儲(chǔ)該線程局部變量在當(dāng)前線程中的值。ThreadLocalMap 使用 ThreadLocal 對(duì)象作為鍵,存儲(chǔ)對(duì)應(yīng)的值。它是一個(gè)自定義的哈希表數(shù)據(jù)結(jié)構(gòu),用于高效地存儲(chǔ)和查找線程局部變量的值。

簡(jiǎn)而言之,ThreadLocal 是用于在每個(gè)線程中存儲(chǔ)和獲取變量的值的類,ThreadLocalMap 是用于實(shí)際存儲(chǔ)線程局部變量的映射表,而 Thread 類則持有每個(gè)線程的 ThreadLocalMap 實(shí)例。它們共同協(xié)作,實(shí)現(xiàn)了線程級(jí)別的數(shù)據(jù)隔離和線程安全。

6. ThreadLocal 內(nèi)存泄露問題?

在使用 ThreadLocal 時(shí),需要注意可能引發(fā)的內(nèi)存泄露問題。如果沒有適當(dāng)?shù)厍謇?ThreadLocal 對(duì)象,會(huì)導(dǎo)致長(zhǎng)時(shí)間運(yùn)行的線程持有對(duì)應(yīng)的 ThreadLocalMap 實(shí)例,從而導(dǎo)致內(nèi)存泄露。

內(nèi)存泄露的一種常見情況是線程池的使用。當(dāng)線程池中的線程執(zhí)行完任務(wù)后,線程不會(huì)被銷毀,而是被線程池保留以供下次使用。如果在任務(wù)中使用了 ThreadLocal,并且沒有手動(dòng)清理 ThreadLocal 對(duì)象,那么線程會(huì)一直持有 ThreadLocalMap 實(shí)例,其中的 Entry 對(duì)象也不會(huì)被釋放,從而導(dǎo)致內(nèi)存泄露。

為了避免 ThreadLocal 內(nèi)存泄露問題,可以采取以下措施:

  • 及時(shí)清理:在使用完 ThreadLocal 后,手動(dòng)調(diào)用 remove() 方法清理對(duì)應(yīng)的 ThreadLocal 對(duì)象。可以在任務(wù)執(zhí)行完畢后或者線程池中的線程即將返回到線程池之前進(jìn)行清理操作。
  • 使用弱引用:可以使用 WeakReference 包裝 ThreadLocal 對(duì)象,這樣當(dāng) ThreadLocal 對(duì)象沒有強(qiáng)引用時(shí),會(huì)被垃圾回收器自動(dòng)回收,并且相應(yīng)的 ThreadLocalMap 中的 Entry 也會(huì)被清理。
  • 使用 InheritableThreadLocal 替代:InheritableThreadLocal 是 ThreadLocal 的一個(gè)子類,它允許子線程繼承父線程的 ThreadLocal 變量。在使用 InheritableThreadLocal 時(shí),需要注意及時(shí)清理,避免子線程持有過多的父線程的 ThreadLocalMap 實(shí)例。

總之,為了避免 ThreadLocal 內(nèi)存泄露,應(yīng)該在合適的時(shí)機(jī)手動(dòng)清理 ThreadLocal 對(duì)象,或者使用弱引用來管理 ThreadLocal 對(duì)象,確保不再需要時(shí)能夠及時(shí)釋放資源。

7. 強(qiáng)引用,軟引用,弱引用,虛引用 分別是什么?

在Java中,有四種引用類型:強(qiáng)引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)和虛引用(Phantom Reference)。

  • 強(qiáng)引用(Strong Reference):強(qiáng)引用是最常見的引用類型,如果一個(gè)對(duì)象具有強(qiáng)引用,即使內(nèi)存不足時(shí)也不會(huì)被垃圾回收器回收。當(dāng)一個(gè)對(duì)象被一個(gè)或多個(gè)強(qiáng)引用所引用時(shí),它是可達(dá)的,不會(huì)被垃圾回收。
  • 軟引用(Soft Reference):軟引用是一種相對(duì)強(qiáng)引用弱化的引用類型。當(dāng)內(nèi)存不足時(shí),垃圾回收器可能會(huì)回收被軟引用引用的對(duì)象。軟引用通常用于對(duì)內(nèi)存敏感的緩存,可以在內(nèi)存不足時(shí)釋放一些緩存對(duì)象,以避免OutOfMemoryError的發(fā)生。
  • 弱引用(Weak Reference):弱引用是比軟引用更弱化的引用類型。當(dāng)垃圾回收器運(yùn)行時(shí),無論內(nèi)存是否充足,都會(huì)回收被弱引用引用的對(duì)象。弱引用通常用于實(shí)現(xiàn)一些特定的功能,如在數(shù)據(jù)結(jié)構(gòu)中標(biāo)記對(duì)象是否已經(jīng)被回收。
  • 虛引用(Phantom Reference):虛引用是最弱化的引用類型,幾乎沒有引用價(jià)值。虛引用主要用于跟蹤對(duì)象被垃圾回收的狀態(tài),無法通過虛引用訪問對(duì)象。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果該對(duì)象只有虛引用,垃圾回收器會(huì)將該虛引用插入一個(gè)引用隊(duì)列中,以通知應(yīng)用程序?qū)ο蟮幕厥涨闆r。

這些引用類型的使用可以幫助開發(fā)者更靈活地管理內(nèi)存和對(duì)象的生命周期。通過選擇適當(dāng)?shù)囊妙愋?,可以避免?nèi)存泄露和優(yōu)化內(nèi)存使用。

8. ThreadLocal 為什么要用弱引用?

實(shí)際上,ThreadLocal 并不是使用弱引用來管理 ThreadLocal 對(duì)象本身,而是使用弱引用來管理 ThreadLocalMap 中的 Entry 對(duì)象。

ThreadLocalMap 是 ThreadLocal 的內(nèi)部類,用于存儲(chǔ)每個(gè)線程的變量副本。每個(gè)線程都有自己的 ThreadLocalMap 實(shí)例,并且在 ThreadLocalMap 中,ThreadLocal 對(duì)象作為鍵,線程的變量副本作為值。

由于 ThreadLocalMap 是每個(gè)線程獨(dú)有的,當(dāng)線程結(jié)束時(shí),ThreadLocalMap 對(duì)象也會(huì)被回收。然而,如果 ThreadLocalMap 中的 Entry 對(duì)象沒有被垃圾回收,那么對(duì)應(yīng)的 ThreadLocal 對(duì)象也不會(huì)被釋放,從而可能導(dǎo)致內(nèi)存泄露。

為了解決這個(gè)問題,ThreadLocalMap 中的 Entry 對(duì)象使用了弱引用來引用 ThreadLocal 對(duì)象。這意味著當(dāng) ThreadLocal 對(duì)象沒有被強(qiáng)引用引用時(shí),會(huì)被垃圾回收器回收,并且相應(yīng)的 Entry 對(duì)象也會(huì)被清理。這樣可以避免因?yàn)?ThreadLocal 對(duì)象被長(zhǎng)時(shí)間引用而導(dǎo)致的內(nèi)存泄露問題。

總結(jié)起來,ThreadLocal 使用弱引用來管理 ThreadLocalMap 中的 Entry 對(duì)象,而不是管理 ThreadLocal 對(duì)象本身。這樣可以確保在 ThreadLocal 對(duì)象沒有被強(qiáng)引用引用時(shí),相關(guān)的 Entry 對(duì)象可以被垃圾回收器回收,避免內(nèi)存泄露的發(fā)生。

以上就是java ThreadLocal線程局部變量常用方法使用場(chǎng)景示例詳解的詳細(xì)內(nèi)容,更多關(guān)于java ThreadLocal局部變量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • idea替換快捷鍵,批量處理對(duì)象的操作

    idea替換快捷鍵,批量處理對(duì)象的操作

    這篇文章主要介紹了idea替換快捷鍵,批量處理對(duì)象的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • MyBatis還是JPA?終于有答案了

    MyBatis還是JPA?終于有答案了

    這篇文章主要介紹了MyBatis還是JPA,中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • springcloud項(xiàng)目占用內(nèi)存好幾個(gè)G導(dǎo)致服務(wù)器崩潰的問題

    springcloud項(xiàng)目占用內(nèi)存好幾個(gè)G導(dǎo)致服務(wù)器崩潰的問題

    這篇文章主要介紹了springcloud項(xiàng)目占用內(nèi)存好幾個(gè)G導(dǎo)致服務(wù)器崩潰的問題,本文給大家分享解決方案供大家參考,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • java獲取本地文件和遠(yuǎn)程文件的方式代碼示例

    java獲取本地文件和遠(yuǎn)程文件的方式代碼示例

    這篇文章主要給大家介紹了關(guān)于java獲取本地文件和遠(yuǎn)程文件的方式,我們項(xiàng)目開發(fā)的時(shí)候,經(jīng)常會(huì)讀取文件,如果文件在本服務(wù)器,則直接用new File()讀取即可,但是有時(shí)候需要遠(yuǎn)程讀取文件,需要的朋友可以參考下
    2023-08-08
  • Spring cloud Eureka注冊(cè)中心搭建的方法

    Spring cloud Eureka注冊(cè)中心搭建的方法

    這篇文章主要介紹了Spring cloud Eureka注冊(cè)中心搭建的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • 關(guān)于Openfire集群源碼的分析

    關(guān)于Openfire集群源碼的分析

    這篇文章主要介紹了關(guān)于Openfire集群源碼的分析,內(nèi)容比較詳細(xì),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • 使用注解解決ShardingJdbc不支持復(fù)雜SQL方法

    使用注解解決ShardingJdbc不支持復(fù)雜SQL方法

    這篇文章主要為大家介紹了使用注解解決ShardingJdbc不支持復(fù)雜SQL方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 實(shí)例分析java對(duì)象中淺克隆和深克隆

    實(shí)例分析java對(duì)象中淺克隆和深克隆

    在本篇文章中我們給大家分享了關(guān)于java對(duì)象中淺克隆和深克隆的相關(guān)知識(shí)點(diǎn)和相關(guān)代碼內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2018-10-10
  • Java開發(fā)利器之Guava?Cache的使用教程

    Java開發(fā)利器之Guava?Cache的使用教程

    緩存技術(shù)被認(rèn)為是減輕服務(wù)器負(fù)載、降低網(wǎng)絡(luò)擁塞、增強(qiáng)Web可擴(kuò)展性的有效途徑之一。今天咱們就來聊聊Guava?Cache本地緩存,感興趣的可以了解一下
    2022-09-09
  • Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    spring Boot默認(rèn)就是使用thymeleaf模板引擎的,下面這篇文章主要給大家介紹了關(guān)于在Spring Boot中利用Thymeleaf發(fā)送Email的方法教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-08-08

最新評(píng)論