ThreadLocal詳解

ThreadLocal詳解

  • 一、故事背景
  • 二、知識點主要構成
    • 1、什么是ThreadLocal?
    • 2、ThreadLocal的基本使用
    • 內存泄漏問題
      • 引用類型:
        • 強引用:
        • 軟引用
        • 弱引用
        • 虛引用
      • ThreadLocal內存泄漏原因
  • 三、總結提升

一、故事背景

最近在學習并發編程相關內容,這里給大家分享一下ThreadLocal如何使用以及不規范的使用ThreadLocal可能會造成的問題。

二、知識點主要構成

1、什么是ThreadLocal?

ThreadLocal叫做線程變量,意思是ThreadLocal中填充的變量屬于當前線程,該變量對其他線程而言是隔離的,也就是說該變量是當前線程獨有的變量。ThreadLocal為變量在每個線程中都創建了一個副本,那么每個線程可以訪問自己內部的副本變量。

ThreadLoal 變量,線程局部變量,同一個 ThreadLocal 所包含的對象,在不同的 Thread 中有不同的副本。因為每個 Thread 內有自己的實例副本,且該副本只能由當前 Thread 使用。這是也是 ThreadLocal 命名的由來。既然每個 Thread 有自己的實例副本,且其它 Thread 不可訪問,那就不存在多線程間共享的問題。ThreadLocal 提供了線程本地的實例。它與普通變量的區別在于,每個使用該變量的線程都會初始化一個完全獨立的實例副本。
在這里插入圖片描述

2、ThreadLocal的基本使用

public class ThreadLocalDemo02 {private ThreadLocal<Person> threadLocal = new ThreadLocal<>();public Person getContent() {return threadLocal.get();}public void setContent(Person person) {threadLocal.set(person);}public static void main(String[] args) {ThreadLocalDemo02 threadLocalDemo02 = new ThreadLocalDemo02();Person person = new Person();person.setName("wmj");new Thread(() ->{threadLocalDemo02.setContent(person);System.out.println(threadLocalDemo02.getContent());}).start();try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}new Thread(()->{System.out.println(threadLocalDemo02.getContent());}).start();}
}

內存泄漏問題

在介紹ThreadLocal造成的內存泄漏問題之前先給大家介紹一下Java中的四種引用類型:

引用類型:

強引用:

最常見的普通對象引用,只要還有一個強引用指向一個對象,就能表明對象還活著,垃圾回收器就不會回收這種對象;

public class Client {public static void main(String[] args) {M m = new M();m = null;System.gc();}
}

軟引用

內存不足時則會觸發gc清理軟引用

public class TestSoftReference {public static void main(String[] args) {//軟引用SoftReference<byte[]> softReference = new SoftReference<>(new byte[1024 * 1024 * 10]);System.out.println(softReference.get());System.gc();try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(softReference.get());byte[] bytes = new byte[1024 * 1024 * 12];System.out.println(softReference.get());}
}

弱引用

GC一旦發現里只具有弱引用的對象,不管當前內存空間是否足夠,都會回收它的內存;

public class WeakDemo {public static void main(String[] args) {WeakReference wr = new WeakReference(new Person());System.out.println(wr.get());System.gc();try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(wr.get());}
}

虛引用

虛引用大多被用于引用銷毀前的處理工作,本次暫不介紹關于虛引用的詳細操作。

ThreadLocal內存泄漏原因

ThreadLocal提供了線程的局部變量,每個線程都可以通過set()和get()來對這個局部變量進行操作,但不會和其他線程的局部變量進行沖突,實現了線程的數據隔離。

Thread為每個線程維護了ThreadLocalMap這么一個Map,而ThreadLocalMap的key是LocalThread對象本身,value則是要存儲的對象。
而key被保存到了弱引用WeakReference對象中,ThreadLocal在沒有外部強引用時,發生GC時會被回收(弱引用就是只要JVM垃圾回收器發現了它,就會將之回收),而這個Entry對象中的value就有可能一直得不到回收,那時就會發生內存泄露。
在這里插入圖片描述

三、總結提升

threadlocl是作為當前線程中屬性ThreadLocalMap集合中的某一個Entry的key值Entry(threadlocl,value),雖然不同的線程之間threadlocal這個key值是一樣,但是不同的線程所擁有的ThreadLocalMap是獨一無二的,也就是不同的線程間同一個ThreadLocal(key)對應存儲的值(value)不一樣,從而到達了線程間變量隔離的目的,但是在同一個線程中這個value變量地址是一樣的。ThreadLocal 適用于每個線程需要自己獨立的實例且該實例需要在多個方法中被使用,也即變量在線程間隔離而在方法或類間共享的場景。

如果本篇博客對您有一定的幫助,大家記得留言+點贊+收藏哦。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36373.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pycharm 安裝庫

這是另一種方式。 搜索到的安裝庫的方式多數是&#xff1a;在桌面上winR鍵運行終端&#xff0c;輸入命令&#xff0c;安裝不了&#xff0c;發現安裝不了。 1、打開pycharm&#xff1b; 2、軟件下部的Terminal終端(需要運行一個代碼才能出現&#xff0c;任何代碼都可)&#xf…

Es、kibana安裝教程-ES(二)

上篇文章介紹了ES負責數據存儲&#xff0c;計算和搜索&#xff0c;他與傳統數據庫不同&#xff0c;是基于倒排索引來解決問題的。Kibana是es可視化工具。 分布式搜索ElasticSearch-ES&#xff08;一&#xff09; 一、ElasticSearch安裝 官網下載地址&#xff1a;https://www…

[C語言] 指針

1. 指針是什么 2. 指針和指針類型 3. 野指針 4. 指針運算 5. 指針和數組 6. 二級指針 7. 指針數組 目錄 1. 指針是什么&#xff1f; 2. 指針和指針類型 2.1 指針-整數 2.2 指針的解引用 3. 野指針 3.1 野指針成因 3.2 如何規避野指針 4. 指針運算 4.1 指針…

不用技術代碼,分班查詢系統怎么做?

暑假即將結束&#xff0c;新學期開始將面臨分班信息公布的工作&#xff01;對于分班信息公布&#xff0c;涉及到學生的個人信息&#xff0c;包括姓名、學號、班級等。在發布這些信息時&#xff0c;必須確保數據的保密性&#xff0c;防止未經授權的人員獲取到學生的個人信息。因…

對字符串中所有單詞進行倒排-C語言/Java

描述 輸入一個字符串&#xff0c;輸出字符串中單詞的倒序。 要求 構成單詞的字符只有26個大寫或小寫英文字母。非構成單詞的字符均視為單詞間隔符&#xff1b;倒排后的單詞間隔符以一個空格表示&#xff1b;如果原字符串中相鄰單詞間有多個間隔符時&#xff0c;倒排轉換后也只…

docker的服務/容器缺少vim問題

背景/問題&#xff1a; docker的服務/容器缺少vim問題 bash: vim: command not found 在docker的mysql服務中安裝Vim 1、執行apt-get update root6d8d17e320a0:/# apt-get update問題:文件下載失敗 Err:1 http://security.debian.org/debian-security buster/updates InRe…

【Linux】程序地址空間

程序地址空間 首先引入地址空間的作用什么是地址空間為什么要有地址空間 首先引入地址空間的作用 1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val 100;6 int main()7 {8 pid_t id fork();9 if(id 0)10 {11 int cn…

自動方向識別式 LSF型電平轉換芯片

大家好&#xff0c;這里是大話硬件。 今天這篇文章想分享一下電平轉換芯片相關的內容。 其實在之前的文章分享過一篇關于電平轉換芯片的相關內容&#xff0c;具體可以看鏈接《高速電路邏輯電平轉換設計》。當時這篇文章也是分析的電平轉換芯片&#xff0c;不過那時候更多的是…

矩陣的轉置

題目&#xff1a; 給你一個二維整數數組 matrix&#xff0c; 返回 matrix 的 轉置矩陣 。 示例 1&#xff1a; 輸入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 輸出&#xff1a;[[1,4,7],[2,5,8],[3,6,9]]class Solution(object):def transpose(self, matrix):"&q…

JMeter 的并發設置教程

JMeter 是一個功能強大的性能測試工具&#xff0c;可以模擬許多用戶同時訪問應用程序的情況。在使用 JMeter 進行性能測試時&#xff0c;設置并發是非常重要的。本文將介紹如何在 JMeter 中設置并發和查看報告。 設置并發 并發是在線程組下的線程屬性中設置的。 線程數&#…

3.解構賦值

解構賦值是一種快速為變量賦值的簡潔語法&#xff0c;本質上仍然是為變量賦值。 3.1數組解構 數組解構是 將數組的單元值快速批量賦值給一系列變量 的簡潔語法 1.基本語法: &#xff08;1&#xff09;賦值運算符左側的[ ]用于批量聲明變量&#xff0c;右側數組的單元值將被賦…

前后端分離------后端創建筆記(04)前后端對接

本文章轉載于【SpringBootVue】全網最簡單但實用的前后端分離項目實戰筆記 - 前端_大菜007的博客-CSDN博客 僅用于學習和討論&#xff0c;如有侵權請聯系 源碼&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

【JavaEE進階】Bean 作用域和生命周期

文章目錄 一. 關于Bean作用域的實例1. lombok2. 實例代碼 二. 作用域定義1. Bean的六種作用域2. 設置作用域 三. Spring 執行流程和 Bean 的生命周期1. Spring 執行流程2. Bean生命周期 一. 關于Bean作用域的實例 注意在此例子中需要用到lombok 1. lombok lombok是什么? Lo…

【C#】判斷打印機共享狀態

打印機共享狀態 /// <summary>/// 打印機共享狀態/// </summary>public enum PrinterShareState{/// <summary>/// 無打印機/// </summary>None -1,/// <summary>/// 未共享/// </summary>NotShare 0,/// <summary>/// 已共享/// …

soap通信2

首先&#xff0c;定義一個XSD&#xff08;XML Schema Definition&#xff09;來描述你的數據結構。在你的Maven項目的src/main/resources目錄下&#xff0c;創建一個名為schemas的文件夾&#xff0c;并在其中創建一個名為scriptService.xsd的文件&#xff0c;內容如下&#xff…

【kubernetes】調度約束

目錄 調度約束 Pod 啟動典型創建過程如下 調度過程 指定調度節點 查看詳細事件&#xff08;發現未經過 scheduler 調度分配&#xff09; 獲取標簽幫助 需要獲取 node 上的 NAME 名稱 給對應的 node 設置標簽分別為 ggls 和 gglm 查看標簽 修改成 nodeSelector 調度方…

vue學習筆記

1.官網 v2官網 https://v2.cn.vuejs.org/ v3官網 https://cn.vuejs.org/ 2.vue引入 在線引入 <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> 下載引入(下載鏈接) https://v2.cn.vuejs.org/js/vue.js 3.初始化渲…

Redis——通用命令介紹

Redis官方文檔 redis官方文檔 核心命令 set 將key和value存儲到Redis中&#xff0c;key和value都是字符串 set key valueRedis中不區分大小寫&#xff0c;字符串類型也不需要添加單引號或者雙引號 get 根據key讀取value&#xff0c;如果當前key不存在&#xff0c;則返回…

Offset Explorer

Offset Explorer 簡介下載安裝 簡介 Offset Explorer&#xff08;以前稱為Kafka Tool&#xff09;是一個用于管理和使Apache Kafka 集群的GUI應用程序。它提供了一個直觀的UI&#xff0c;允許人們快速查看Kafka集群中的對象以及存儲在集群主題中的消息。它包含面向開發人員和管…

RANSAC算法

RANSAC簡介 RANSAC(RAndom SAmple Consensus,隨機采樣一致)算法是從一組含有“外點”(outliers)的數據中正確估計數學模型參數的迭代算法。 “外點”一般指的的數據中的噪聲&#xff0c;比如說匹配中的誤匹配和估計曲線中的離群點。所以&#xff0c;RANSAC也是一種“外點”檢…