专栏首页用户4352451的专栏ThreadLocal浅入浅出

ThreadLocal浅入浅出

一、概述

ThreadLocal类用来提供线程内部的局部变量。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是private static类型。 总结:ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。

ThreadLocal的主要应用场景为按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。例如:同一个网站登录用户,每个用户服务器会为其开一个线程,每个线程中创建一个ThreadLocal,里面存用户基本信息等,在很多页面跳转时,会显示用户信息或者得到用户的一些信息等频繁操作,这样多线程之间并没有联系而且当前线程也可以及时获取想要的数据。

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID). Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

核心意思是

ThreadLocal 提供了线程本地的实例。它与普通变量的区别在于,每个使用该变量的线程都会初始化一个完全独立的实例副本。ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都可被回收。

总的来说,ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景。后文会通过实例详细阐述该观点。另外,该场景下,并非必须使用 ThreadLocal ,其它方式完全可以实现同样的效果,只是 ThreadLocal 使得实现更简洁。

原理

  • 既然我们明白了ThreadLocal的作用那我们的试着想一下他是如何实现的呢?? 他是同一个线程共享一个变量。那么我们是不是首先要找个东西来存储这个变量呢?存储的容积也就那几种,Map,list,等。那就用Map吧,一个Key一个Value,value来存储共享的变量,那么这个key就必须能保证是这个线程,那我们就把线程自己存储进去呗,还有就是这个map放在哪里呢??还有并发问题,内存泄露问题,等等。。。。想不下去那接下来我们来看看ThreadLocal的源码是如何实现的呢? -在JDK中ThreadLocal的map是写在Thread中的,每个Thread都会有自己的Map(ThreadLOcalMap),从而就解决了因并发问题导致的Map线程不安全的问题(具体的内容可以深入去看一下ThreadLocal的源码)
  • 如果这个ThreadLocals这个map和具体的实例是有映射的,所以说有可能会导致内存泄露的问题,在源码中会将这个ThreadLocal这个key为设置为弱引用,在java中弱引用的特点是只要发生GC 就会将这个变量清理掉。(tips:硬软弱虚java中的四种引用方式)。大概在这个提一下了解具体原因请自行看源码

总结

  • ThreadLocal 并不解决线程间共享数据的问题
  • ThreadLocal 通过隐式的在不同线程内创建独立实例副本避免了实例线程安全的问题 每个线程持有一个 Map 并维护了 ThreadLocal 对象与具体实例的映射,该 Map 由于只被持有它的线程访问,故不存在线程安全以及锁的问题
  • ThreadLocalMap 的 Entry 对 ThreadLocal 的引用为弱引用,避免了 ThreadLocal 对象无法被回收的问题
  • ThreadLocalMap 的 set 方法通过调用 replaceStaleEntry 方法回收键为 null 的 Entry 对象的值(即为具体实例)以及 Entry 对象本身从而防止内存泄漏 ThreadLocal 适用于变量在线程间隔离且在方法间共享的场景

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 秒懂Java并发和线程安全

    在平时写代码的时候我们经常会说“这会不会有线程安全问题,是不是得加把锁呢?”,细细的品一下这句话,是包涵很多知识点在里面。线程?,线程安全?,什么时候才会出现线...

    居士
  • 浅析线程池参数设置

    首先先明确一下线程池的主要作用是什么 线程池解决的核心问题就是资源管理问题。在并发环境下,系统不能够确定在任意时刻中,有多少任务需要执行,有多少资源需要投入。...

    居士
  • springBoot 线程池异步编程

    2、基于注解进行参数的配置 在config包下,创建PayThreadPoolConfig.java配置类:

    居士
  • ThreadLocal解决了什么问题

    由于 ThreadLocal 支持范型,如 ThreadLocal< StringBuilder >,为表述方便,后文用 变量 代表 ThreadLocal 本...

    程序员小明
  • 线程的私有领地 ThreadLocal

    从名字上看,『ThreadLocal』可能会给你一种本地线程的概念印象,可能会让你联想到它是一个特殊的线程。

    Single
  • ThreadLocal父子线程数据传递方案

    介绍InheritableThreadLocal之前,假设对 ThreadLocal 已经有了一定的理解,比如基本概念、原理。在讲解之前我们先列举有关Threa...

    黄泽杰
  • 经典面试题-线程状态

    cwl_java
  • Java 多线程之线程的生命周期 | 图解

    在 Java 初中级面试中,关于线程的生命周期可以说是常客了。本文就针对这个问题,通过图文并茂的方式详细说说。

    本人秃顶程序员
  • WordPress最新版本网站安全漏洞详情与修复

    wordpress 目前互联网的市场占有率较高,许多站长以及建站公司都在使用这套开源的博客建站系统来设计网站,wordpress的优化以及html静态化,深受g...

    技术分享达人
  • 秋招面经三(作业帮、新浪、阿里云)

    位码即tcp标志位,有6种标示:SYN(synchronous建立联机) 、ACK(acknowledgement 确认) 、PSH(push传送)、 FIN(...

    鹏-程-万-里

扫码关注云+社区

领取腾讯云代金券