最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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ù)庫(kù)連接管理:

public class DBConnectionManager {
    private static ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
    public static void openConnection() {
        // 獲取數(shù)據(jù)庫(kù)連接并設(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ù)庫(kù)連接
        Connection connection = connectionThreadLocal.get();
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                // 異常處理
            }
        }
        // 清理 ThreadLocal 變量
        connectionThreadLocal.remove();
    }
}

在多線程的數(shù)據(jù)庫(kù)訪問場(chǎng)景中,可以使用 ThreadLocal 管理數(shù)據(jù)庫(kù)連接。每個(gè)線程都可以通過 getConnection() 方法獲取自己獨(dú)立的數(shù)據(jù)庫(kù)連接,而不會(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)文章

  • 帶你快速搞定java并發(fā)庫(kù)

    帶你快速搞定java并發(fā)庫(kù)

    本文主要介紹了java高并發(fā)寫入用戶信息到數(shù)據(jù)庫(kù)的幾種方法,具有很好的參考價(jià)值。下面跟著小編一起來看下吧,希望能給你帶來幫助
    2021-07-07
  • springboot整合druid的完整流程記錄

    springboot整合druid的完整流程記錄

    Java程序很大一部分要操作數(shù)據(jù)庫(kù),為了提高性能操作數(shù)據(jù)庫(kù)的時(shí)候,又不得不使用數(shù)據(jù)庫(kù)連接池,Druid是阿里巴巴開源平臺(tái)上一個(gè)數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn),結(jié)合了DBCP等DB池的優(yōu)點(diǎn),同時(shí)加入了日志監(jiān)控,這篇文章主要介紹了springboot整合druid的相關(guān)資料,需要的朋友可以參考下
    2026-02-02
  • javax.validation.constraints.NotNull找不到的問題及解決

    javax.validation.constraints.NotNull找不到的問題及解決

    文章主要介紹了Java Bean驗(yàn)證注解的使用,包括`@NotNull`、`@AssertFalse`、`@DecimalMax`、`@Pattern`等,并提供了每個(gè)注解的使用范例
    2026-02-02
  • Maven中jar包下載失敗的幾種解決方法

    Maven中jar包下載失敗的幾種解決方法

    本文主要介紹了Maven中jar包下載失敗的幾種解決方法,包括配置國(guó)內(nèi)Maven源、刪除本地jar包目錄重新下載,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • SpringCloud通過Feign傳遞List類型參數(shù)方式

    SpringCloud通過Feign傳遞List類型參數(shù)方式

    這篇文章主要介紹了SpringCloud通過Feign傳遞List類型參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 淺談Java中的this作為返回值時(shí)返回的是什么

    淺談Java中的this作為返回值時(shí)返回的是什么

    Java中的this作為返回值時(shí)返回的是什么?下面小編就為大家介紹一下Java中的this作為返回值時(shí)返回。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • 實(shí)例講解MyBatis如何防止SQL注入

    實(shí)例講解MyBatis如何防止SQL注入

    這篇文章通過實(shí)例代碼介紹MyBatis如何防止SQL注入,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Java中的有限狀態(tài)機(jī)(設(shè)計(jì)模式——狀態(tài)模式)

    Java中的有限狀態(tài)機(jī)(設(shè)計(jì)模式——狀態(tài)模式)

    這篇文章主要介紹了Java中的有限狀態(tài)機(jī)(設(shè)計(jì)模式——狀態(tài)模式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java 類型信息詳解和反射機(jī)制介紹

    Java 類型信息詳解和反射機(jī)制介紹

    這篇文章主要介紹了Java 類型信息詳解和反射機(jī)制介紹,需要的朋友可以參考下
    2020-11-11
  • 基于Java中的StringTokenizer類詳解(推薦)

    基于Java中的StringTokenizer類詳解(推薦)

    下面小編就為大家?guī)硪黄贘ava中的StringTokenizer類詳解(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05

最新評(píng)論

城步| 徐汇区| 屏东县| 霍邱县| 大厂| 呼伦贝尔市| 象山县| 汉川市| 芮城县| 邹城市| 定西市| 泰来县| 阳泉市| 谢通门县| 裕民县| 宜兰市| 库车县| 新疆| 广安市| 大埔县| 兴宁市| 左云县| 三都| 新蔡县| 确山县| 清苑县| 大埔县| 务川| 琼海市| 阳高县| 青州市| 大理市| 新民市| 贵溪市| 聂荣县| 博客| 全椒县| 应城市| 临高县| 萨迦县| 新营市|