欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java多線(xiàn)程編程之ThreadLocal詳解

 更新時(shí)間:2023年09月28日 09:37:33   作者:汪xiao羊  
這篇文章主要介紹了Java多線(xiàn)程編程之ThreadLocal詳解,ThreadLocal是Java中的一個(gè)線(xiàn)程局部變量,該變量在多線(xiàn)程并發(fā)執(zhí)行時(shí),為每個(gè)線(xiàn)程都提供了一個(gè)獨(dú)立的副本,簡(jiǎn)單來(lái)說(shuō),ThreadLocal提供了一種在多線(xiàn)程環(huán)境中,使每個(gè)線(xiàn)程綁定自己獨(dú)立的變量的方法,需要的朋友可以參考下

一、介紹

ThreadLocal是Java中的一個(gè)線(xiàn)程局部變量,該變量在多線(xiàn)程并發(fā)執(zhí)行時(shí),為每個(gè)線(xiàn)程都提供了一個(gè)獨(dú)立的副本。

簡(jiǎn)單來(lái)說(shuō),ThreadLocal提供了一種在多線(xiàn)程環(huán)境中,使每個(gè)線(xiàn)程綁定自己獨(dú)立的變量的方法,每個(gè)線(xiàn)程可以獨(dú)立地改變自己的副本,而不會(huì)影響其他線(xiàn)程所對(duì)應(yīng)的副本。

二、特性

1. 獨(dú)立副本

每個(gè)線(xiàn)程都擁有一個(gè)獨(dú)立的變量副本,每個(gè)線(xiàn)程都可以隨意訪問(wèn)自己的副本,互不影響。

2. 高效性

為了提高性能,每個(gè)線(xiàn)程都只需要?jiǎng)?chuàng)建一個(gè)變量副本,不需要考慮線(xiàn)程安全。

3. 封裝性

變量的創(chuàng)建和存儲(chǔ)都被封裝起來(lái),無(wú)需關(guān)心具體的實(shí)現(xiàn)方式。

三、原理

ThreadLocal是通過(guò)一個(gè)ThreadLocalMap實(shí)現(xiàn)線(xiàn)程安全的,這個(gè)Map存儲(chǔ)了每個(gè)線(xiàn)程的變量副本。

每個(gè)線(xiàn)程都有一個(gè)唯一的ThreadLocalMap,它可以用來(lái)存儲(chǔ)數(shù)據(jù)。

ThreadLocalMap是ThreadLocal的一個(gè)內(nèi)部靜態(tài)類(lèi),用于存儲(chǔ)ThreadLocal變量的值,它的key為T(mén)hreadLocal對(duì)象的弱引用,value則是該ThreadLocal對(duì)象的值。

ThreadLocalMap解決了線(xiàn)程不安全問(wèn)題,每個(gè)線(xiàn)程都會(huì)有自己獨(dú)立的變量副本,避免了線(xiàn)程安全問(wèn)題。

同時(shí)也避免了使用線(xiàn)程同步造成的性能問(wèn)題,提高了并發(fā)性。

四、注意事項(xiàng)

1. 內(nèi)存泄漏

如果創(chuàng)建ThreadLocal后沒(méi)有及時(shí)調(diào)用remove方法清除對(duì)應(yīng)的值,則會(huì)導(dǎo)致內(nèi)存泄漏。

2. 并發(fā)問(wèn)題

雖然每個(gè)線(xiàn)程都有自己的變量副本,但是在多線(xiàn)程環(huán)境下,要注意副本之間的線(xiàn)程安全問(wèn)題。

3. 適度使用

ThreadLocal雖然很有用,但是并不適合存儲(chǔ)大量的數(shù)據(jù),每個(gè)線(xiàn)程都會(huì)有獨(dú)立的副本,如果存儲(chǔ)過(guò)多的數(shù)據(jù),會(huì)導(dǎo)致內(nèi)存占用過(guò)大。

4. 使用頻率

ThreadLocal的使用頻率應(yīng)該在實(shí)際需要時(shí)使用,而不是作為一種普通習(xí)慣或者無(wú)腦使用。例如,在請(qǐng)求處理的過(guò)程中,當(dāng)需要將某個(gè)參數(shù)或者對(duì)象放到ThreadLocal中時(shí),在處理完成后,一定要記得及時(shí)清除,避免出現(xiàn)內(nèi)存泄露的情況。

5. 內(nèi)存消耗

ThreadLocal的不當(dāng)使用也容易導(dǎo)致內(nèi)存消耗過(guò)高,特別是使用多了、不及時(shí)清除、值的尺寸過(guò)大等因素都會(huì)造成暴漲,尤其是在高并發(fā)和長(zhǎng)時(shí)間的情況下,可能引起內(nèi)存溢出,因此也需要謹(jǐn)慎使用和控制內(nèi)存占用。

6. 生命周期問(wèn)題

ThreadLocal的生命周期只受聲明周期短的對(duì)象的影響,例如Java中使用它的方法的生命周期,因此,一個(gè)對(duì)象的使用應(yīng)該與其聲明周期相同。在Servlet中使用它必須關(guān)閉它,而不是將它保留在一個(gè)公共靜態(tài)域中。如果Servlet沒(méi)有正確地關(guān)閉,可能會(huì)導(dǎo)致內(nèi)存泄漏或線(xiàn)程之間的數(shù)據(jù)混亂。

7. 單例模式

在使用ThreadLocal實(shí)現(xiàn)單例模式時(shí),需要注意它的線(xiàn)程安全性。在多線(xiàn)程環(huán)境下,如果需要共享一個(gè)對(duì)象的時(shí)候,需要使用ThreadLocal保證線(xiàn)程安全。這種方式需要注意,每個(gè)線(xiàn)程使用的是不同的實(shí)例,因此狀態(tài)不會(huì)被共享,否則可能會(huì)出現(xiàn)線(xiàn)程間相互影響而導(dǎo)致數(shù)據(jù)異常的問(wèn)題。

五、使用案例

1. 案例一

(1) 場(chǎng)景

解決SimpleDateFormat線(xiàn)程不安全的問(wèn)題,同時(shí)提高了代碼的執(zhí)行效率。

(2) 代碼

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
 * DateFormatThreadLocal
 * 該案例為解決SimpleDateFormat線(xiàn)程不安全的問(wèn)題,同時(shí)又提高了代碼的執(zhí)行效率,避免了重復(fù)創(chuàng)建和銷(xiāo)毀對(duì)象的開(kāi)銷(xiāo)。
 *
 * @author wxy
 * @since 2023-05-08
 */
public class DateFormatThreadLocal {
    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT_THREAD_LOCAL = ThreadLocal
            .withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    public static void main(String[] args) {
        for (; ; ) {
            new Thread(() -> {
                Date date = new Date();
                System.out.println(Thread.currentThread().getName() + ":" + format(date));
            }).start();
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public static String format(Date date) {
        SimpleDateFormat simpleDateFormat = DATE_FORMAT_THREAD_LOCAL.get();
        System.out.println(Thread.currentThread().getName() + ":" + "實(shí)例地址: " + simpleDateFormat);
        return simpleDateFormat.format(date);
    }
}

這里通過(guò)創(chuàng)建一個(gè)ThreadLocal對(duì)象保證了每個(gè)線(xiàn)程使用的DateFormat對(duì)象是獨(dú)立的,而且ThreadLocal使用完畢時(shí)要調(diào)用其remove()方法清除線(xiàn)程之間的引用,防止出現(xiàn)內(nèi)存泄漏。使用ThreadLocal避免了SimpleDateFormat線(xiàn)程不安全的問(wèn)題,同時(shí)提高了代碼的執(zhí)行效率,避免了重復(fù)創(chuàng)建和銷(xiāo)毀對(duì)象的開(kāi)銷(xiāo)。

到此這篇關(guān)于Java多線(xiàn)程編程之ThreadLocal詳解的文章就介紹到這了,更多相關(guān)Java的ThreadLocal內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能

    springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)郵箱驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 詳解Java打包鏡像部署

    詳解Java打包鏡像部署

    這篇文章主要介紹了Java打包鏡像部署,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • SpringBoot如何讀取resources目錄下的文件

    SpringBoot如何讀取resources目錄下的文件

    這篇文章主要介紹了SpringBoot如何讀取resources目錄下的文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 詳解java==運(yùn)算符和equals()方法的區(qū)別

    詳解java==運(yùn)算符和equals()方法的區(qū)別

    這篇文章主要介紹了java==運(yùn)算符和equals()方法的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • IntelliJ IDEA中Tomcat日志亂碼問(wèn)題的解決指南

    IntelliJ IDEA中Tomcat日志亂碼問(wèn)題的解決指南

    在使用IntelliJ IDEA進(jìn)行Java開(kāi)發(fā)時(shí),Tomcat作為常用的服務(wù)器,往往被集成在開(kāi)發(fā)環(huán)境中,許多開(kāi)發(fā)者可能會(huì)遇到這樣一個(gè)問(wèn)題:?jiǎn)?dòng) Tomcat 服務(wù)器時(shí),控制臺(tái)的日志輸出出現(xiàn)了亂碼,本文將詳細(xì)介紹如何通過(guò)修改IntelliJ IDEA和Tomcat的相關(guān)配置,徹底解決日志輸出亂碼的問(wèn)題
    2024-10-10
  • Java新特性之Optional類(lèi)超詳細(xì)介紹

    Java新特性之Optional類(lèi)超詳細(xì)介紹

    這篇文章主要給大家介紹了關(guān)于Java新特性之Optional類(lèi)超詳細(xì)介紹的相關(guān)資料,Java8中的Optional類(lèi)是一個(gè)容器對(duì)象,可以包含null或非null值,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • SpringBoot?@DS注解實(shí)現(xiàn)多數(shù)據(jù)源配置以及問(wèn)題解決辦法

    SpringBoot?@DS注解實(shí)現(xiàn)多數(shù)據(jù)源配置以及問(wèn)題解決辦法

    這篇文章主要給大家介紹了關(guān)于SpringBoot?@DS注解實(shí)現(xiàn)多數(shù)據(jù)源配置以及問(wèn)題解決辦法,所謂多數(shù)據(jù)源就是一個(gè)Java EE項(xiàng)目中采用了不同數(shù)據(jù)庫(kù)實(shí)例中的多個(gè)庫(kù),或者是同一個(gè)數(shù)據(jù)庫(kù)實(shí)例中的多個(gè)不同庫(kù),需要的朋友可以參考下
    2023-11-11
  • Java中分割字符串的兩種方法實(shí)例詳解

    Java中分割字符串的兩種方法實(shí)例詳解

    這篇文章主要介紹了Java中分割字符串的兩種方法,一種是java.lang.String 的 split() 方法,,另外一種是用String Tokenizer類(lèi)。文中的每種方法都給出了詳細(xì)的示例代碼,相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起看看吧。
    2016-12-12
  • SpringBoot整合mybatis/mybatis-plus實(shí)現(xiàn)數(shù)據(jù)持久化的操作

    SpringBoot整合mybatis/mybatis-plus實(shí)現(xiàn)數(shù)據(jù)持久化的操作

    這篇文章主要介紹了SpringBoot整合mybatis/mybatis-plus實(shí)現(xiàn)數(shù)據(jù)持久化,本節(jié)內(nèi)容我們介紹了數(shù)據(jù)持久化的相關(guān)操作,并且是基礎(chǔ)傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)——mysql,需要的朋友可以參考下
    2022-10-10
  • 簡(jiǎn)單了解springboot中的配置文件相關(guān)知識(shí)

    簡(jiǎn)單了解springboot中的配置文件相關(guān)知識(shí)

    這篇文章主要介紹了簡(jiǎn)單了解springboot中的配置文件相關(guān)知識(shí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評(píng)論