首页 > 其他分享 >TheadLocal类学习

TheadLocal类学习

时间:2024-05-07 15:56:31浏览次数:18  
标签:count Task thread ID 学习 线程 TheadLocal pool

ThreadLocal 是 Java 中一个非常实用的线程相关的类,它提供线程本地变量,即每个线程都有自己独立的变量副本,从而避免了线程安全问题。下面我将通过几个方面来帮助你理解并学习如何使用 ThreadLocal

基本概念

  • 线程局部变量:每个线程都拥有一份 ThreadLocal 变量的副本,彼此之间互不影响,这使得在多线程环境下可以做到数据隔离,提高程序的并发能力。
  • 应用场景:适用于每个线程需要独立的资源或状态的情况,比如数据库连接、事务管理、线程专属的缓存、记录日志时的线程ID等。

使用步骤

  1. 创建 ThreadLocal 实例:指定泛型类型,表示存储在其中的变量类型。
  2. 设置值:通过 set 方法为当前线程设置值。
  3. 获取值:通过 get 方法获取当前线程对应的值。
  4. 清理:使用完毕后,可以通过 remove 方法清理当前线程的值,避免内存泄漏。

例:应用:如何使用ThreadLocal为每个线程创建独立的计数器

 1 import java.util.concurrent.ExecutorService;
 2 import java.util.concurrent.Executors;
 3 
 4 
 5 /**
 6  * 在这个示例中,尽管使用了ThreadLocal来存储每个线程的计数,但由于线程池中的线程会被复用,
 7  * 当一个线程完成一个任务并开始处理下一个任务时,之前设置在ThreadLocal中的计数值没有被清除。
 8  *
 9  * 因此,第二个任务开始时,它可能会继承上一个任务在该线程中设置的计数,导致数据看起来像是“交叉污染”。
10  */
11 public class ThreadLocalMisuseExample {
12 
13     // 静态ThreadLocal变量,用于存储当前线程的计数
14     private static final ThreadLocal<Integer> threadCounter = ThreadLocal.withInitial(() -> 0);  // 或  new ThreadLocal<>();但是为初始化为0
15 
16     public static void main(String[] args) {
17         ExecutorService executor = Executors.newFixedThreadPool(2); // 创建固定大小的线程池
18 
19         // 提交任务到线程池
20         for (int i = 0; i < 4; i++) {
21             int taskId = i;
22             executor.submit(() -> {
23                 Integer count = threadCounter.get();
24                 System.out.println("Task ID " + taskId + " on thread " + Thread.currentThread().getName()
25                         + ", initial count: " + count);
26                 threadCounter.set(count + 1); // 增加计数
27                 System.out.println("Task ID " + taskId + " on thread " + Thread.currentThread().getName()
28                         + ", updated count: " + threadCounter.get());
29 
30                 // 修正交叉污染问题:清除ThreadLocal变量,防止数据污染
31                // threadCounter.remove();
32             });
33         }
34 
35         executor.shutdown();
36     }
37 }

 

结果1:

Task ID 1 on thread pool-1-thread-2, initial count: 0
Task ID 0 on thread pool-1-thread-1, initial count: 0
Task ID 1 on thread pool-1-thread-2, updated count: 1
Task ID 0 on thread pool-1-thread-1, updated count: 1
Task ID 2 on thread pool-1-thread-1, initial count: 1
Task ID 2 on thread pool-1-thread-1, updated count: 2
Task ID 3 on thread pool-1-thread-2, initial count: 1
Task ID 3 on thread pool-1-thread-2, updated count: 2

 

结果2: 即把31行 注释放开 // threadCounter.remove();

--修正后,每个Task的两个thread计数:initial为0、updated为1

Task ID 0 on thread pool-1-thread-1, initial count: 0
Task ID 1 on thread pool-1-thread-2, initial count: 0
Task ID 1 on thread pool-1-thread-2, updated count: 1
Task ID 0 on thread pool-1-thread-1, updated count: 1
Task ID 2 on thread pool-1-thread-2, initial count: 0
Task ID 3 on thread pool-1-thread-1, initial count: 0
Task ID 3 on thread pool-1-thread-1, updated count: 1
Task ID 2 on thread pool-1-thread-2, updated count: 1

 

例2:其它使用ThreadLocal导致的串号问题:如  Server通常使用ThreadPool来接受处理请求,而ThreadPool中的Thread是复用的。

 

标签:count,Task,thread,ID,学习,线程,TheadLocal,pool
From: https://www.cnblogs.com/wxdlut/p/18177511

相关文章

  • Python学习笔记(一)
    Python简介Python是GuidovanRossum发布于1991年的一种计算机程序设计语言。是一种动态的、面向对象的脚本语言,是一种解释型的,弱类型的高级计算机语言。需要注意的是python有2.x和3.x两个不兼容的版本,这是个历史遗留问题。python3.x将是趋势,所以这里选择的是python3.x。Python的......
  • 【机器学习】第三节-回归分析
    目录一、线性回归1.一元线性回归2.二元线性回归3.多元线性回归4.总结二、逻辑回归一、线性回归1.一元线性回归\[f(x)=ax+b\]均方误差最小化(最小二乘法)即找到一条直线,使所有样本到直线上的欧式距离之和最小\[min\sum_{i=1}^{m}(f(x_i)-y_i)^2=min\sum_{i=1}{m}(y_i-wx_i-b......
  • nndl-1 机器学习基础
    nndl-1机器学习基础nndl系列参考:https://github.com/nndl/nndl.github.io绪论深度学习:是机器学习的一个分支,从有限样例中通过算法总结出一般性的规律,并可以应用到新的未知数据上贡献度分配问题:深度学习模型由组件组成,我们并不知道每个组件的贡献是多少人工神经网络ANN:信息......
  • 哈希基础知识学习-python版
    哈希哈希表根据key直接进行访问的无序数据结构,复杂度为O(1)哈希表的实现---字典初始化d1=dict()查找#使用中括号[]进行查找,括号内为特定的键,键-值dic={"a":1,"d":0,"e":3}print(dic["a"])#输出1print(dic["z"])#报错修改dic["a"]=5print(dic[&quo......
  • Pytorch入门—Tensors张量的学习
    Tensors张量的学习张量是一种特殊的数据结构,与数组和矩阵非常相似。在PyTorch中,我们使用张量来编码模型的输入和输出,以及模型的参数。张量类似于NumPy的ndarrays,只是张量可以在GPU或其他硬件加速器上运行。事实上,张量和NumPy数组通常可以共享相同的底层内存,从而无需复制数据(请参......
  • ssrf-基于Pikachu的学习
    SSRFSSRF漏洞原理攻击与防御(超详细总结)-CSDN博客原理服务端请求伪造(ServerSideRequestForgery,SSRF)指的是攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。比如......
  • url重定向-基于Pikachu的学习
    URL重定向原理不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话就可能发生"跳错对象"的问题。转发由服务器端进行的页面跳转。请求转发......
  • Unity热更学习toLua使用--[1]toLua的导入和默认加载执行lua脚本
    [0]toLua的导入下载toLua资源包,访问GitHub项目地址,点击下载即可。将文件导入工程目录中:导入成功之后会出现Lua菜单栏,如未成功生成文件,可以点击GenerateAll重新生成(注意很可能是路径问题导致的生成失败!)之后就可以开始编写脚本执行第一个lua程序了![1]C#调用Lua脚本编写C#......
  • 算法学习笔记(16):Link Cut Tree
    LinkCutTree简称LCT(不是LiChaoTree),是一种非常强大的数据结构。声明该博客写来很大部分目的是帮助自己理解,笔者水平有限,没办法完全原创,有很多内容源自于OI-wiki,和网上博客,见谅。功能考虑一些问题:树上单点查,树上路径修改,这是树上差分可以解决的。那么如果路径查,......
  • 刘铁猛C#学习笔记(草稿)
    C#笔记目录C#笔记刘铁猛网课005C#语言基本元素概览、初识变量与方法、算法简介构成C#语言的基本元素初识类型、变量和方法算法简介作业006,007详解类型、变量与对象(重要)006详解类型、变量与对象上什么是类型(Type)类型在C#语言中的作用007详解类型、变量与对象下C#语言的类型系统......