对于ThreadLocal的理解

news/2024/5/20 6:37:32 标签: juc, 并发

对于ThreadLocal的理解

  • 什么是ThreadLocal
    • ThreadLocal的使用场景
        • 1.线程隔离
        • 2.跨函数传值
      • 正确使用
        • 感想

什么是ThreadLocal

在Java的多线程并发执行的过程中,为了保证多个线程对变量的安全访问,可以将变量放到ThreadLocal类型的对象中,是变量在每一个线程中都有独立的值,不会出现一个线程读取变量时被另一个线程修改的现象。ThreadLocal类通常被翻译为本地变量类或者线程局部变量。
ThreadLocal位于JDK的java.lang核心包中。如果程序创建了一个ThreadLocal实例,那么在访问这个变量的值时,每个线程都会拥有一个独立的、自己的本地值。“线程本地变量”可以看成专属于线程的变量,不受其他线程干扰,保存着线程的专属数据。当线程结束后,每个线程所拥有的那个本地值会被释放。在多线程并发操作“线程本地变量”的时候,线程各自操作的是自己的本地值,从而规避了线程安全问题。
ThreadLocal本质上相当于Map<key,value>,同时threadLocal可以很好的额解决线程安全的问题,它通过为每一个线程提供一个独立的本地值去解决并发冲突问题。在很多情况下,使用ThreadLocal比直接使用同步锁解决问题更加方便,且程序拥有更高的并发性。

public class ThreadLocalTest02 {

    public static void main(String[] args) {

        ThreadLocal<String> local = new ThreadLocal<>();

        IntStream.range(0, 10).forEach(i -> new Thread(() -> {
            local.set(Thread.currentThread().getName() + ":" + i);
            System.out.println("线程:" + Thread.currentThread().getName() + ",local:" + local.get());
        }).start());
    }
}

输出结果:
线程:Thread-0,local:Thread-0:0
线程:Thread-1,local:Thread-1:1
线程:Thread-2,local:Thread-2:2
线程:Thread-3,local:Thread-3:3
线程:Thread-4,local:Thread-4:4
线程:Thread-5,local:Thread-5:5
线程:Thread-6,local:Thread-6:6
线程:Thread-7,local:Thread-7:7
线程:Thread-8,local:Thread-8:8
线程:Thread-9,local:Thread-9:9

ThreadLocal的使用场景

1.线程隔离

ThreadLocal主要的价值在于线程隔离,ThreadLocal中的数据只属于当前线程,其本地值对别的线程是不可见的,在多下线程环境下可以防止自己的变量被其他线程篡改。另外由于每个线程之间相互隔离,避免了同步加锁带来的性能影响。

T和read在线程隔离常用的案例为:可以为每一个线程保存一个会话信息、数据库连接、Http请求,这样一个线程所有调用到的处理函数都可以非常方便的访问这些资源。最常见的就是使用ThreadLocal实现数据库连接独享、Session数据管理等

2.跨函数传值

通常用于同一个线程中,在跨类,方法去传递数据时,如果不使用ThreadLoccal,那么相互之间的数据传递就必须依靠返回值和参数,这样就无形之中增加了这些类或者方法之间的耦合度。由于ThreadLocal的特性,同一线程在某些地方进行设置,在该线程任何地方放都可获取到。线程执行过程中所所执行的函数都可以读写ThreadLocal变量的本地治,从而实现跨函数的值传递。
这点就很让人容易联想到越权的问题,在使用security框架时,这个问题很好解决,我们可以从 SecurityContextHolder中得到登录用户的所有信息,但是如果没有使用 Security框架呢,那么ThreadLocal或许就是一个很好的解决办法。

.

正确使用

ThreadLocal内部的ThreadLocalMap的key使用的时弱引用指向ThreadLocal的实例对象,当该实例对象被回收的时候,如果ThreadLocalMap的key使用的也是强引用指向ThreadLocal那么该实例就不会被回收,也就会造成内存泄漏的问题。
同时使用弱引用也会出现类似问题,当ThreadLocal实例被回收时,弱引用也被回收时,key值为null,但是value值不为null这也会造成内存泄漏,但是这个问题我们可以通过调用ThreadLocal的remove方法解决。

感想

juc是真的难,太痛苦了,本来以为jvm就够难了,但是当我打开juc的书翻开第二页,我就知道我错了,每个字都会读,合到一起就看不懂了,希望多看几遍能够理解吧。阿弥陀佛!


http://www.niftyadmin.cn/n/119079.html

相关文章

泼辣修图Polarr5.11.4 版,让你的创意无限延伸

泼辣修图是一款非常实用的图片处理软件&#xff0c;它不仅拥有丰富的图片处理功能&#xff0c;而且还能够轻松地实现自定义操作。泼辣修图的操作界面非常简洁&#xff0c;功能也非常丰富&#xff0c;使用起来非常方便快捷。 泼辣修图拥有非常丰富的图片处理功能&#xff0c;包括…

华为机试题:HJ105 记负均正II(python)

文章目录&#xff08;1&#xff09;题目描述&#xff08;2&#xff09;Python3实现&#xff08;3&#xff09;知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

MAX 10 10M50 FPGA(10M50DDF256I7G)10M50DDF484C8G/10M50DDF484I7G

MAX 10器件是单芯片、非易失性低成本可编程逻辑器件(pld)&#xff0c;用于集成最优的系统组件集。MAX 10设备的亮点包括&#xff1a;内部存储双配置闪存用户闪存即时支持集成模数转换器(adc)支持Nios II单芯片软核处理器该器件设备是系统管理、I/O扩展、通信控制平面、工业、汽…

王道计算机组成原理课代表 - 考研计算机 第七章 输入输出系统 究极精华总结笔记

本篇博客是考研期间学习王道课程 传送门 的笔记&#xff0c;以及一整年里对 计算机组成 知识点的理解的总结。希望对新一届的计算机考研人提供帮助&#xff01;&#xff01;&#xff01; 关于对 “输入输出系统” 章节知识点总结的十分全面&#xff0c;涵括了《计算机组成原理》…

【LeetCode】带环链表两道题

第一题&#xff1a;环形链表 问题介绍 给你一个链表的头节点head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪next指针再次到达&#xff0c;则链表中存在环。为了表示给定链表中的环&#xff0c;评测系统内部使用整数pos 来表示链表…

C++之类模板

前言 类封装了属性和方法&#xff0c;而这些属性和方法都有他们自己的数据类型&#xff0c;在有些特殊场景&#xff0c;我们希望我们的类里的这些属性和方法的类型能够在使用的时候再指定&#xff0c;因为我们并无法事先判断这个类的使用者会传什么类型给到这个类&#xff0c;…

sql数据库常用操作指令

一、操作库-- 创建库create database db1;-- 创建库是否存在&#xff0c;不存在则创建create database if not exists db1;-- 查看所有数据库show databases;-- 查看某个数据库的定义信息 show create database db1; -- 修改数据库字符信息alter database db1 character set ut…

Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号

首先区分一下Linux信号跟进程间通信中的信号量&#xff0c;它们的关系就犹如老婆跟老婆饼一样&#xff0c;没有一毛钱的关系。 信号的概念 信号的概念&#xff1a;信号是进程之间事件异步通知的一种方式&#xff0c;属于软中断。比如&#xff1a;红绿灯是一种信号&#xff0c…