ThreadLocal

ThreadLocal详解 ThreadLocal详解都在里面了.. 阅读详情

ThreadLocal的核心是:每个线程都可以通过ThreadLocal对象的 get 或 set 方法来访问属于自己的,独立初始化的变量拷贝。

ThreadLocal 介绍

  • 我们想要在多线程当中拥有某个类的多个独立的私有化实例对象而不造成冲突。每个对象唯一对应一个线程。这其中(指ThreadLocal)便是实现了线程安全。

  • 有一点需要注意的是,ThreadLocal变量是全局可访问的。我们可以从线程中的任何一个地方来访问它。同时注意,TheadLocal 变量是被声明为static 和final的。

什么是线程安全?

一个线程相当于一个单一的流水线执行过程。当我们谈及多线程应用时,指的是多个流水线执行着相同的代码(感觉这里说得不太对,但原文就是:we mean that there multiple(sequential flow of control) line of process that runs through the same lines of code.)。这种情况下,就有可能出现某个线程访问或修改另一个线程的数据。如果我们不允许这种情况出现,就得使它能够线程安全。以下是几种实现线程安全的操作:
- 重入(Re-entrancy, java 里有个重入锁类: ReentrantLock , 实现的是可被中断的同步)
- 同步执行 Mutual exclusion(synchronization)
- Thread-local
- 原子操作 (Atomic operation)

根据上面说的可,ThreadLocal也是实现线程安全的一种选择,现在我们看看ThreadLocal如何实现。

ThreadLocal 的用法

这里我不禁引用 Joshua Bloch 的话(对于这一节我还有什么更好的人选),以下是他的原话(这几句原话都不太理解,估计翻译不对,都附上原话。。):

  • 单纯每个线程的上下文, 例如 用户id 或者 交易id(transaction id)。都能很好工作。在线程退出的时候能够轻松地进行资源释放和清除工作。不会产生内存泄漏。( Genuine per-thread context, such as user id or transaction id. Works great. Easy to clean up when the thread exits the scope. No leaks.)

  • 每个线程的性能(Per-thread instances for performance.)

  • 当你不注意控制好回调的时候,脏数据将产生(“Sleazing” values through callbacks that you don’t control:):有时候,你必须调用一个回调你的函数的库函数(sometimes you must call a library method that calls back into your package)。这个时候,由于库函数的缺点,你无法自己将自己需要的上下文信息传递给自己(you need some context that you were unable to pass to yourself)。这种罕见的情况,thread locals将会成为你的救命恩人。

以上几个要点,用我自己的话来讲就是:我们拥有一个非线程安全的对象,当我们想要安全地使用它。我们可以 通过将该对象包裹于 synchronized 代码块中来实现同步。另一个方法就是使用ThreadLocal,它通过为每个线程持有分开的独立的对象拷贝来使其线程安全。

ThreadLocal实例

package com.javapapers;

import java.text.SimpleDateFormat;
import java.util.Date;

public class ThreadLocalExample {
    private static final ThreadLocal formatter = new ThreadLocal() {

        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date) {
        return formatter.get().format(date);
    }
}

在上面的例子中, get() 方法是理解的关键。它返回了当前线程对于这个thread-local变量的一份拷贝。如果该变量对于当前线程没有值,则会先进行初始化为 initialValue 方法的返回值。

java文档中的例子

下面的类为每个线程生成唯一的本地识别码(即id)。一个线程在它第一次调用ThreadId.get()的时候便获得了它的id,并且在后续调用过程中保持不变。

import java.util.concurrent.atomic.AtomicInteger;

 public class ThreadId {
     // Atomic integer containing the next thread ID to be assigned
     private static final AtomicInteger nextId = new AtomicInteger(0);

     // Thread local variable containing each thread's ID
     private static final ThreadLocal threadId =
         new ThreadLocal() {
             @Override protected Integer initialValue() {
                 return nextId.getAndIncrement();
         }
     };

     // Returns the current thread's unique ID, assigning it if necessary
     public static int get() {
         return threadId.get();
     }
 }
ThreadLocal在Java API中的使用

在JDK1.7中有了一个新的类叫ThreadLocalRandom。它可以用于为并行的线程产生随机数。随机数种子对于每个线程都是唯一的。这真是个很酷的工具。

以下是该类中对于ThreadLocal的使用:

    private static final ThreadLocal localRandom =
        new ThreadLocal() {
            protected ThreadLocalRandom initialValue() {
                return new ThreadLocalRandom();
            }
    };
ThreadLocalRandom 的使用例子
package com.javapapers;

import java.util.concurrent.ThreadLocalRandom;

public class ThreadLocalRandomExample {

    public static void main(String args[]) throws InterruptedException {

        //tossing 3 coins
        for (int i = 0; i < 3; i++) {
            final Thread thread = new Thread() {

                public void run() {
                    System.out.print(Thread.currentThread().getName() + ":");

                    // generating 3 random numbers - random for every thread
                    for (int j = 0; j < 3; j++) {
                        final int random = ThreadLocalRandom.current().nextInt(
                                1, 3);
                        System.out.print(random + ",");
                    }
                    System.out.println();
                }
            };
            thread.start();
            thread.join();
        }
    }
}

ThreadLocal与内存泄漏

ThreadLocal本身并不坏,它是个很有用的工具API。当着但这完全取决于我们如何使用它。我们应该学着在恰当的情况下选择合适的工具。我们不能用炮弹来攻击蚊子, 却责怪炮弹本身。

网上弥漫着对于ThreadLocal的强烈抱怨,说它会导致内存泄漏。大部分情况下,不是这样的!

我又想引用 Joshua Bloch 的话:
“…thead local本身并没有错,它们并没有导致内存泄漏,也并不慢。它们比非thread-local的副本更加本地化(local, 或者翻译为私有吧)(例如,它们有更好的信息隐藏属性)。他们有可能被误用,当然,大多数其他的编程工具也是如此…”

原文:http://javapapers.com/core-java/threadlocal/

【ThreadLocal源码】深入浅出ThreadLocal ThreadLocal提供线程局部变量。这些变量与正常的变量不同,因为每一个线程在访问ThreadLocal实例的时候,都有自己的、独立初始化的变量副本。ThreadLocal实例通常是类中的私有静态变量,使用它的目的是希望将状态(用户ID、事务ID等)与线程关联起来。1)、前面执行的方法保存了信息后,后续方法可以通过ThreadLocal 直接获取到,避免了传参,类似于全局变量的概念,例如当前登录用户放入ThreadLocal 中,避免每个方法一直传递过去,直接从ThreadLocal获取即可; 阅读详情

相关推荐

AXI_IIC读写操作

其实在之前调试过一次AXI_IIC,没调试通,碍于赶进度,就直接使用了zynq-PS侧的IIC,就一直搁置着了,这次抽空将这部分内容继续调试下去,这一次没花多少时间就调通了,现在将我的调试过程,经历,以及参考文档如下: 参考文档:pg090-axi-iic.pdf 参考链接:https://forums.xilinx.com/t5/Design-and-Debug-Techniques-Blog/IIC-Protocol-and-Programming-Sequence/ba-p/1072248 上面的这个

qq_32134427的博客 1万+

ThreadLocal原理、ThreadLocal的使用、ThreadLocal内存泄漏、ThreadLocal的坑

文章目录背景说明一:ThreadLocal的原理1.1 什么是ThreadLocal变量1.2 ThreadLocal实现原理1.3 ThreadLocalMap实现原理1.4 ThreadLocalMap结构图二:ThreadLocal的使用2.1 创建ThreadLocal工具类2.2 在拦截器/过滤器中通过用户token获取登录信息,并与当前线程绑定2.3 业务处理时获取用户信息2.4 当前请求结束时,销毁ThreadLocal变量三:ThreadLocal的坑、ThreadLocal内存泄漏3.1

weixin_49114503的博客 8909

银河麒麟(ky10)x86与arm双架构下编译zlmediakit的实战指南

本文提供了在银河麒麟(ky10)操作系统上,针对x86与arm双架构编译部署流媒体服务器zlmediakit的完整实战指南。文章详细阐述了从环境准备、依赖安装、代码获取到编译构建与测试的全过程,重点解析了两种CPU架构下的关键差异与注意事项,帮助开发者高效完成国产化平台上的流媒体服务搭建。

weixin_29306875的博客 98

muduo之ThreadLocal

ThreadLocal用来存储线程私有数据的类。 // Use of this source code is governed by a BSD-style license // that can be found in the License file. // // Author: Shuo Chen (chenshuo at chenshuo dot com) #ifn...

1万+

基于opencv-ANN的水果识别模型训练

本文通过opencv-ann-mlp训练模型,实现对五种水果进行分类识别。本文详细介绍该项目的各个过程,包括数据准备、预处理、样本读取、训练数据集制作、训练标签制作、模型参数设置、模型训练,模型测试验证等,总结该过程需要注意的事项。

qq_15985873的博客 3973

【系统架构设计师】2026年上半年真题论文:论高并发系统的设计与实践

本文围绕高并发系统架构设计展开,重点论述了电商秒杀系统的实战经验。文章采用"痛点-解决方案-效果"的逻辑结构,从缓存设计、异步处理、限流降级、数据库优化等6个维度详细阐述了应对高并发的技术策略。其中,重点介绍了多级缓存体系、基于消息队列的异步处理机制和微服务拆分实践,并辅以实际案例说明如何解决超卖、缓存雪崩等典型问题。全文强调高并发设计需要系统性思维,通过空间换时间、异步换吞吐、横向换能力等原则,最终实现系统吞吐量从500TPS提升至20000TPS的性能突破。

数据知道的博客 1157

理解ThreadLocal

ThreadLocal是什么早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为T

Java之道 27万+

62. 如何通过增强(Enhancement) 的方式给 SAP ABAP 标准程序增添新功能

本文通过一个实际的例子,介绍了如何不通过修改 SAP 标准 ABAP 程序源代码的方式,对其的功能进行增强,即采取 ABAP 增强开发的方式进行二次开发,这是一种在实际 SAP 项目实施过程中使用非常广泛的技术。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3306

ThreadLocal对象

ThreadLocal,即线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。这 个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值,也就是是说可以让线程与保存值的关联起来,让每个线程都有一个自己的变量,实现线程安全。 可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法获取到原先设置的值。 在代码清单4-15所示的例子中,构建了一个常用的Profiler类,它具有begin()和end()两个 方法,而e

tian830937的专栏 720

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的远距离停车位检测系统(深度学习代码+UI界面+训练数据集)

本文详细介绍了基于YOLOv5/YOLOv6/YOLOv7/YOLOv8深度学习模型的远距离停车位检测系统的完整实现方案。该系统能够准确识别200米范围内的停车位状态,为智能停车场管理系统、自动驾驶车辆提供关键的视觉感知能力。文章涵盖算法原理、数据集构建、模型训练、系统实现及优化策略,并提供完整的代码实现和UI界面设计。关键词:YOLO系列,深度学习,停车位检测,计算机视觉,智能交通系统pythonimport cv2import os"""创建数据存储目录""""""定时采集图像"""

YOLO 185

JAVA:Spring Boot 集成 Forest 优雅的 HTTP 客户端

Forest是一个优雅的Java HTTP客户端框架,通过注解式声明简化HTTP接口调用。它支持多HTTP客户端、自动参数绑定、序列化、重试机制和拦截器等功能。本文演示了如何在Spring Boot中集成Forest,包括配置、接口定义和调用示例,还展示了POST请求、文件上传等常见场景。相比传统HTTP客户端,Forest具有声明简洁、功能完善的特点,特别适合微服务调用和第三方API对接,能显著提升开发效率和代码可维护性。

木头 427

threadLocal原理

一.ThreadLocal的作用   ThreadLocal提供的实际上就是一种线程隔离,不同的线程的变量归属不同的线程,线程之间不能想问访问各自的变量,当线程生命周期结束的时候,线程会被销毁。 二.ThreadLocal的原理 Thread类中有一个成员变量threadLocals: 这个ThreadLocalMap 是ThreadLocal类中一个静态内部类; ThreadLocal类中最主要的就是set 方法get方法; set方法 这个getMap(t); 传入一个Thr.

sam19911的博客 5531

MATLAB 与 STK 互联导出导弹轨迹及速度数据(csv导出)

本文介绍了如何通过 MATLAB 脚本连接 STK 提取导弹三维轨迹数据,并以 CSV 格式导出,包含以下关键内容:自动连接 STK 场景;获取所有导弹对象;提取 J2000 坐标系下的位置和速度;加入任务优先级与状态;导出为标准 CSV 文件;

weixin_52370774的博客 778

ThreadLocal 详解

1. ThreadLocal 是用来干什么的 ThreadLocal 是一个以 ThreadLocal 对象为键、任意对象为值的存储结构,这个结构被附带在线程上,也就是说一个线程可以根据一个 ThreadLocal 对象查询到一个绑定在这个线程上的值。 2. ThreadLocal 示例 代码如下: public class TestThreadLocal { private static final ThreadLocal<String> STRING_THREAD_LOCAL = n

明月燃雨 7813

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

线程副本之ThreadLocal

ThreadLocal,即线程变量,是一个以ThreadLocal对象为键,任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到一个绑定到这个线程上的值。 可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法 获取到原先设置的值。 **代码示例:**构建了一个常用的Profiler类,它具 有begin()和end()两个方法,而end()方法返回从begin()方法调用开始到 end()方法被调用时的时间差,单位是毫秒。 publi

weixin_43902350的博客 316

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

详解ThreadLocal

Thread存储线程独有的变量(存储多个变量(值)时,可以创建多个ThreadLocal用来存储),以供在整个线程存活过程中取用。这种能力由ThreadLocal中的ThreadLocalMap实现。Thread在存储自己独有变量时,ThreadLocal实例在该Thread环境内使用set方法实现变量(值)存储。(继续探究原理)实际是静态内部类ThreadLocalMap将该变量(值)以key=ThreadLocal实例,value=变量(值)的键值对对象Entry形式存储到了ThreadLocalMap

文化园 4543

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

利用threadLocal实现对执行时间的统计

import java.util.Properties; import java.util.concurrent.TimeUnit; import static java.util.concurrent.TimeUnit.*; /* * 利用 threadLocal 实现 对执行时间的统计 * */ public class Profiler { private static final ThreadLocal<Long> TIME_THREADLOCAL = new Thread.

yt438936731的博客 1223

什么是ThreadLocal?如何正确使用ThreadLocal?

多个线程同时读写同一个共享变量会造成并发问题,一种解决方案就是避免变量共享。我们可以使用**线程封闭**技术,即使用局部变量,每个线程都有各自的调用栈,局部变量就存在栈帧中,不会与其他线程共享。我们还可以使用线程本地存储ThreadLocal。

深页 2251

Threadlocal是什么,有什么用

Threadlocal定义 Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的ThreadLocal变量。 Threadlocal的使用场景 就是当我们只想在本身的线程内使用的变量,可以用 ThreadLocal 来实现,并且这些变量是和线程的生命周期密切相关的...

qq_33411202的博客 975
上一篇: Resource interpreted as Stylesheet but transferred with MIME type text/plain
下一篇: Java 中几个不常用的关键字
沉默的大东
博客等级 码龄12年 6粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值