Java 并发编程 ThreadLocal

Unity VR 零基础开发之 Pico4 MR 2、弹出弹窗后,点击Android选项,然后再点击Switch Platform按钮切换成安卓平台。3、切换完成后Android选项后面会显示unity图标。 阅读详情

​ThreadLocal源码分析  线程变量透传  如何避免脏数据  内存溢出

2014年拍摄于甘南藏族自治区桑科草原,喜欢阴天

微信公众号

王皓的GitHub:https://github.com/TenaciousDWang

 

今天这回说一下ThreadLocal这个类。

 

ThreadLocal为变量在每个线程中都创建了一个独立副本,那么每个线程可以访问自己内部的副本变量,其他线程不能访问,所以不会产生线程安全问题,但是ThreadLocal无法解决共享变量更新问题,依然需要线程同步。

 

这里引用《码出高效》里面CS的例子进行改造来说一下ThreadLocal的使用方法和场景。

 

在CS中每人对应三个数值,子弹数,杀敌数,自己的血量,初始值分别为1500,0,10.假设每个人属于一个线程,这三个初始值写在什么地方呢?每一个线程写死的话,如果同意修改子弹数量了呢?如果共享,由于每个人,每个线程对数据操作不同会导致数据不准确,这时我们就可以使用ThreadLocal对象,设置为共享变量,统一设置初始值,但是每个线程都有一个副本是独立的,对其他线程不可见的,《码出高效》中对于ThreadLocal的名称解释为CopyValueIntoEveryThread就显得非常贴切。

 

 

首先我们看一下ThreadLocal创建时通常都是使用private static 来修饰的。

 

代码示例中并没有对ThreadLocal进行set操作,而是重写了initialValue方法返回一个共享变量,我们来看一下ThreadLocal的get操作的源码。

 

 

源码中,每一个Thread都包含一个ThreadLocalMap,ThreadLocal的get方法实际上是从这个Map中获取Entry,再从Entry中获取当前副本的值,如果无法获取,调用setInitialValue方法。

 

 

其中如果当前线程没有ThreadLocalMap就创建,有的话会set进一个初始键ThreadLocal<T>对应值为initialValue方法返回,这是一个保护方法。

 

 

这里我们之前重写了initialValue方法不返回null,而是返回了我们定义的共享变量。

 

接下来我们在线程的run方法内写入ThreadLocal变量减去随机的int值,并打印每一个线程对应的三个值的结果。这里为了结果容易分辨,我加了一个锁,让其按顺序打印。

 

 

我们可以看一下打印的结果,每一个线程的副本变量都只对自己可见,对其他线程不可见,打印的都是线程自己对自己副本变量操作的结果,线程间不会互相干扰,可以看出是线程安全的。

 

以上是每个线程对自己的变量副本进行操作,如果是多线程对共享变量进行更新则ThreadLocal无法解决,我们依旧需要线程同步,例子如下,将变量改为可变对象StringBuilder,注意其兄弟StringBuffer是线程安全的。

 

 

此时sb这个ThreadLocal是一个StringBuilder线程不安全的可变对象,我们起十个线程来对其添加-i,我们来看一下运行结果。

 

 

我们看到开始打印为正常顺序,到后面时,已经变为乱序,因此当有多线程引用共享变量时,依旧需要线程同步的,ThreadLocal并不能解决共享变量多线程操作的安全问题。

 

接下来看一下ThreadLocal使用中需要注意的脏数据,内存泄漏问题。

 

A、脏数据,我们知道线程池属于复用线程,也就是说线程中的ThreadLocal也会被复用,如果下一个线程没有set初始值,那么就有可能get到上一下线程用过的信息,或者上一个线程没有进行ThreadLocal的remove操作。

 

B、内存泄漏。

 

 

源码注释中写道,ThreadLocal对象通常最为私有静态变量使用,其生命周期不会随着线程结束而结束,所以必须及时调用remove方法来清理,避免内存泄漏。

 

总结上述线程使用ThreadLocal三个重要方法需要注意的问题:

 

1、set:如果没有set操作ThreadLocal,容易引起脏数据问题。

 

2、get:始终没有get操作的ThreadLocal是没有意义的。

 

3、remove:如果没有remove操作,容易引起内存泄漏问题。

 

最后说一个ThreadLocal子类InheritableThreadLocal用于子线程共享父线程本地变量的功能,也就是线程透传功能。

 

举一个例子,先来看一下基本使用方法与场景。

 

 

main为父线程,创建InheritableThreadLocal,然后在父线程中创建子线程threadTest,我们看一下运行结果。

 

 

可以获得父线程内变量的值。为什么能获取到呢,我们来看一下InheritableThreadLocal的源码来分析一下。

 

 

InheritableThreadLocal继承自ThreadLocal,并且重写了父类的方法:createMap,getMap,childValue。createMap中使用了Thread中的inheritableThreadLocals我们来看一下它会被怎么赋值。

 

 

会把parent也就是父线程,使用createInheritedMap方法来把父线程的inheritableThreadLocals中不是null的线程变量都copy过来。

 

 

所以子线程可以获取到父线程的线程内变量。但是InheritableThreadLocal其实在使用线程池时也存在脏数据的问题,目前的解决方案是使用alibaba的开源项目transmittable-thread-local来解决这个问题。大家可以上github上自行查看使用说明,写的很详细。

 

最后说一个是关于SimpleDateFormat,是一个线程不安全的类,定义为static会有同步风险,多线程共享时会产生错误。《码出高效》推荐使用ThreadLocal来解决。

 

 

好了,这就是今天要说Java并发编程ThreadLocal,喜欢请关注~

 

 

 

 

【异常】安装OpenClaw遇到 Windows环境pnpm安装node-llama-cpp postinstall生命周期脚本执行失败完整解决方案 摘要: Windows环境下使用pnpm安装node-llama-cpp时,postinstall脚本执行失败(错误码3221225477),主要因缺少C++编译工具链或预构建二进制下载失败。解决方案: 基础排查:确保管理员权限、Node.js ≥18、路径无中文; 安装编译工具:推荐Visual Studio的“C++桌面开发”组件或windows-build-tools; 环境变量配置:强制CPU模式+国内镜像(NODE_LLAMA_CPP_FORCE_CPU=true,镜像地址替换为国内源); pnp 阅读详情

相关推荐

IFIX往Mysql数据库同步数据方法

通过IFix数据库向Mysql数据库同步数据

仙人掌 1595

java 脏数据_Java程序的脏数据问题是什么?

脏数据(Out-of-date data),指过时的数据。如果在您的Java程序中存在脏数据,将或多或少地给软件系统带来一些问题,如:无法实时地应用已经发生改变的配置,软件系统出现一些莫名其妙的、难以重现的、后果严重的错误等等。尽量避免脏数据的存在是非常有价值的。本文希望能在这方面给同行们一点帮助。Fragment 1。 缓存技术的脏数据问题/*** A report printer is use...

weixin_39619270的博客 569

dummy机械臂代码学习(六)

CLI-Tool文件夹下又包含四个子文件夹,以及一个gitignore文件、一个run_shell.py的python文件、一个run.bat文件和一个zadig exe文件。库解析命令行参数,并根据不同的命令执行相应的操作。Zadig是一个用于Windows操作系统的开源工具,它的主要功能是安装和配置USB驱动程序。的目的呢就是确保在版本控制过程中,不必要的或自动生成的文件被忽略掉,来保持代码仓库的干净和整洁。,DummyStudio的软件作者已放在GitHub,我们主要看CLI-Tool文件夹就行。

jumaohhh的博客 1432

ThreadLocal详解和如何解决ThreadLocal的内存泄漏问题

一:ThreadLocal简介: 从Java官方文档中的描述:ThreadLoacl类用来提供线程内部的局部变量,这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static 类型的,用于关联线程和线程上下文。 我们可以得知ThreadLoacl的作用是:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的声明周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂

weixin_43156133的博客 1233

告别串口升级!手把手教你为STM32H750的W25Q32制作MDK下载算法(QSPI篇)

本文详细介绍了为STM32H750的W25Q32制作MDK下载算法(QSPI篇)的完整流程,帮助开发者告别低效的串口烧录方式。通过定制下载算法,可实现20倍以上的烧录速度提升,支持完整的调试功能,显著提高开发效率。文章涵盖环境准备、核心算法实现、性能优化及常见问题解决方案,适合嵌入式开发者参考。

weixin_30735745的博客 403

STM32CubeMX最新版下载安装全攻略(附官网访问问题解决方案)

本文提供了STM32CubeMX最新版的详细下载与安装指南,并针对国内开发者常见的官网访问缓慢、注册验证邮件延迟等问题,给出了实用的解决方案和备选策略。通过清晰的步骤解析,帮助用户快速部署这一强大的STM32图形化配置工具,从而高效启动嵌入式开发项目。

weixin_28256233的博客 193

ThreadLocal 缓存存入线程,防止其他出现线程污染问题

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34186950的博客 959

YOLOv5 自定义模型 Android 部署完整指南

本文详细介绍了将YOLOv5模型部署到Android设备的完整流程,包含三个核心部分:首先验证官方模型测试,确保基础环境配置正确;随后进行模型转换,从PyTorch导出ONNX格式并优化,再转换为NCNN格式;最后在Android项目中集成自定义模型,包括文件替换、参数修改和代码适配。教程基于YOLOv5 6.1版本,使用NCNN框架进行移动端推理,涵盖了常见问题解决方案和关键配置要点,为开发者提供了从训练到部署的完整技术路线。

FJN110的博客 591

Java高并发的情况下如果出现共享变量,如何保证线程安全的解决方案

此文为我个人理解,如有不正确欢迎指正 一、ThreadLocal 首先,我们简单的了解一下线程安全,简单的举例来说,当10个客户端同时请求同一个接口,这样就产生了10个线程,当这10个线程需要共享一个变量时,就可能出现脏读等线程安全问题。ThreadLocal便解决了这个问题。ThreadLocal会把每一个线程变量的值存储到本地,线程之间不共用数据,从而杜绝数据脏读等问题 private sta...

weixin_39891166的博客 5837

飞牛NAS打造成童年经典游戏机

这篇文章介绍如何使用飞牛NAS搭建经典游戏模拟器。首先需开启Docker并下载RetroArch-web镜像,随后创建容器并设置端口映射。启动后上传游戏ROM文件(如NES格式),在模拟器中加载即可游玩。文章以修改版坦克大战为例,详细说明按键配置方法。同时还提到公网访问需配置DDNS或使用ZeroTier内网穿透。通过这套方案,用户可以在NAS上重温红白机等经典游戏体验。

dgnankai的专栏 884

HTML5+CSS3+JS小实例:焦点图波浪切换动画特效

实例:焦点图波浪切换动画特效。字体图标库:Font Awesome。技术栈:HTML+CSS+JS。

艾恩小灰灰的博客 907

java并发编程之ThreadLocal

不管用那种语言,在并发编程中遇见的问题都是类似的,只不每种语言提供的方法和工具不一样而已。 对于每个线程独享某个对象或者每个线程独立保存信息的场景,java提供的解决方法是ThreadLocal , 对于线程独享某个对象的例子 public class ThreadLocalDemo { public static ExecutorService threadPool = Executors.newFixedThreadPool(16); SimpleDateFormat dateForma

acethan的博客 186

ESP32-C3入门教程 基础篇⑩——SNTP(Simple Network Time Protocol) 网络时间同步的简单实例

ESP32-C3入门教程 基础篇⑩——SNTP(Simple Network Time Protocol) 网络时间同步的简单实例

1589

Java并发编程——ThreadLocal

ThreadLocal详解

m0_62909831的博客 1243

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ThreadLocal实战:Java并发编程中的利器

要点 | 描述 || ThreadLocal | 用于线程隔离的利器,适用于高并发场景 || 线程安全 | 通过为每个线程绑定变量副本实现线程之间的数据隔离 || 性能 | 高吞吐量、低延迟 |ThreadLocal是Java并发编程中的利器,在高并发场景下,可以有效解决线程安全问题。随着技术的不断发展,ThreadLocal将在更多场景中得到应用。未来,我们期待看到更多关于ThreadLocal的创新和突破。

南客先生的博客 871

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java并发编程-ThreadLocal总结

ThreadLocal并不属于java.util.concurrent.*包的内容,但却是并发编程中很重要也比较常用的一个类,它的核心思想是数据隔离。 1.ThreadLocal作用 在并发编程中时常有这样一种需求:每条线程都需要存取一个同名变量,但每条线程中该变量的值均不相同。 如果是你,该如何实现上述功能?常规的思路如下: 使用一个线程共享的Map<Thread,Object>,M...

冒烟儿的专栏 499

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java并发编程之ThreadLocal原理解析

1.ThreadLocal内部结构 1.1 常见误解 如果我们不去看源代码的话,可能会猜测ThreadLocal是这样子设计的: 每个ThreadLocal都创建一个Map,然后用线程作为Map的key,要存储的局部变量作为Map的value,这样就能达到各个线程的局部变量隔离的效果。这是最简单的设计方法,JDK最早期的ThreadLocal 确实是这样设计的,但现在早已不是了。 1.2 现在的设计 但是,JDK后面优化了设计方案,在JDK8中 ThreadLocal的设计是: 每个Thread维护一个T

weixin_45803046的博客 212

Java并发编程之 ThreadLocal

多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的另一种保证一种规避多线程访问出现线程不安全的方法,当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量这样就不会存在线程不安全问题。 ThreadLocal是JDK包提供的,它提供线程本地变量,如果创建一个ThreadLocal变量,那么访问这个变量的每个线

qq_43613793的博客 582

Java并发编程之ThreadLocal使用及源码解析

Java并发编程之ThreadLocal使用及源码解析创建ThreadLocal及其操作创建ThreadLocal进行ThreadLocal的相应操作ThreadLocal初始值设置ThreadLocal 延迟设置值ThreadLocal子类InheritableThreadLocalThreadLocal源码 Java ThreadLocal类允许你创建只能由同一线程读写的变量。因此,即使两个线程执行相同的代码,并且代码引用相同的ThreadLocal变量,两个线程也不能看到彼此的ThreadLocal变

HQ DevJ的专栏 306

Java并发编程基础--ThreadLocal

Java并发编程基础之ThreadLocal ​ ThreadLocal是一个线程变量,但本质上是一个以ThreadLocal对象为键、任意对象为值的存储结构,这个结构依附在线程上,线程可以根据一个ThreadLocal对象查询到绑定这个线程上的一个值。 1. ThreadLocal的起源 ​ 在Java 1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLoca...

一只特立独行的猪 201

java并发编程面试之ThreadLocal深度解析

ThreadLocal是Java提供的一种线程局部变量机制。它允许我们在每个线程中创建一个独立的变量副本,这个副本只能被当前线程访问和修改。ThreadLocal主要用来解决多线程环境下共享变量的并发访问问题,为每个线程提供独立的变量,从而避免了线程安全问题。

qq_33129875的博客 1062

Java并发编程之ThreadLocal深度探索

ThreadLocal是Java提供的一个线程级别的变量,它可以为每个使用该变量的线程提供一个独立的副本,这样每个线程都可以独立地改变自己的副本而不影响其他线程。由于ThreadLocal使用的是弱引用,如果线程执行完毕但没有清理ThreadLocal,那么这个线程所持有的ThreadLocal变量将无法被垃圾回收。在多线程的Web应用中,每个请求对应一个线程,可以使用ThreadLocal来存储请求的上下文信息,如用户信息、请求参数等。二、ThreadLocal的使用场景。

N201871643的博客 1101

Java并发编程之ThreadLocal详解

ThreadLocal简介变量值的共享可以使用public static的形式,所有线程都使用同一个变量,如果想实现每一个线程都有自己的共享变量该如何实现呢?JDK中的ThreadLocal类正是为了解决这样的问题。ThreadLocal类并不是用来解决多线程环境下的共享变量问题,而是用来提供线程内部的共享变量,在多线程环境下,可以保证各个线程之间的变量互相隔离、相互独立。在线程中,可以通过get...

Stay Hungry, Stay Foolish 4万+

Java并发编程:深入剖析ThreadLocal

原文 Java并发编程:深入剖析ThreadLocal   想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理。首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两个应用场景。   以下是本文目录大纲:   一.对ThreadLoc...

dashumao0228的博客 92

java并发编程(二)ThreadLocal

java并发编程(二)ThreadLocal 多钱程访问同一个共享变量时特别容易出现并发问题,特别是在多个线程需要对一个 共享变量进行写入时。 为了保证线程安全,一般使用者在访问共享变量时需要进行适当的 同步。 同步的措施一般是加锁,这就需要使用者对锁有一定的了解, 这显然加重了使用者的 负担。 那么有没有一种方式可以做到,当创建一个变量后, 每个线程对其进行访问的时候 访问的是自己线程的变量呢?...

Tong_Nan的博客 227

Java并发编程之基础篇(三) -- ThreadLocal

Java并发编程之基础篇(三) – ThreadLocal ThreadLocal介绍 上篇文章讲到,如果想在多线程的环境下,实现共享可变资源的安全访问,最好的方式是加锁,也就是同一时刻只有一个线程在使用共享可变资源。如果我们有一种方式可以根除对变量的共享,那么就可以实现不加锁的情况下对变量进行安全访问。 还拿之前抢卫生间坑位的例子举例,如果只有一个卫生间坑位,五个人都想去卫生间的话,那么就需要加锁同步。如果给每个人都提供一个单独的坑位,那么就可以不加锁了,因为没有争抢的场景发生。 Java通过Thread

IT界的一只菜鸟 289
上一篇: Java 内存模型与volatile特性深入分析
下一篇: Java BlockingQueue 阻塞式队列
JavaBoy王皓
博客等级 码龄11年 23粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值