我的编程空间,编程开发者的网络收藏夹
学习永远不晚

彻底理解Java 中的ThreadLocal

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

彻底理解Java 中的ThreadLocal

 ThreadLocal是什么

  早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。

  当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

  从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

  所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。

ThreadLocal的接口方法

ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:

  • void set(Object value)设置当前线程的线程局部变量的值。
  • public Object get()该方法返回当前线程所对应的线程局部变量。
  • public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
  • protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

  值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

  ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本:

package com.test; public class TestNum {  // ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值  private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {   public Integer initialValue() {    return 0;   }  };  // ②获取下一个序列值  public int getNextNum() {   seqNum.set(seqNum.get() + 1);   return seqNum.get();  }  public static void main(String[] args) {   TestNum sn = new TestNum();   // ③ 3个线程共享sn,各自产生序列号   TestClient t1 = new TestClient(sn);   TestClient t2 = new TestClient(sn);   TestClient t3 = new TestClient(sn);   t1.start();   t2.start();   t3.start();  }  private static class TestClient extends Thread {   private TestNum sn;   public TestClient(TestNum sn) {    this.sn = sn;   }   public void run() {    for (int i = 0; i < 3; i++) {     // ④每个线程打出3个序列值     System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["        + sn.getNextNum() + "]");    }   }  } } 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

彻底理解Java 中的ThreadLocal

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

彻底理解Java 中的ThreadLocal

ThreadLocal是什么  早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。  当使用T
2023-05-31

彻底理解 Python 生成器

1. 生成器定义在Python中,一边循环一边计算的机制,称为生成器:generator。 2. 为什么要有生成器列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费
2023-01-30

AndroidOkHttp代理与路由的彻底理解

这篇文章主要为大家介绍了AndroidOkHttp代理与路由的彻底理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-09

彻底理解Redis持久化

前言大家都知道Redis一个内存数据库,它支持2种持久化方式:RDB(Snapshot 内存快照),AOF(append only file)。持久化功能将内存中的数据同步到磁盘来避免Redis发生异常导致数据丢失的情况。当Redis实例重启时,即可利用之前持
彻底理解Redis持久化
2017-07-16

彻底理解Python list切片原理

关于list的insert函数 list#insert(ind,value)在ind元素前面插入value首先对ind进行预处理:如果ind<0,则ind+=len(a),这样一来ind就变成了正数下标预处理之后,当ind<0时,ind=0
2022-06-05

一文带你彻底剖析Java中Synchronized原理

Synchronized是Java中的隐式锁,它的获取锁和释放锁都是隐式的,完全交由JVM帮助我们操作,在了解Synchronized关键字之前,首先要学习的知识点就是Java的对象结构,本文介绍的非常详细,需要的朋友可以参考下
2023-05-18

java中ThreadLocal的基本原理

目录基本流程ThreadLoalMap数据结构Hash冲突及解决ThreadLocal内存泄露内存引用链路引用类型为什么使用弱引用而不是强引用泄露原因分析ThreadLocal应用场景源码实现一个线程内可以存多个ThreadLocal对象,存储的位置位于Thr
2015-05-05

如何彻底理解Go指针

如何彻底理解Go指针,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。什么是指针?简单点说,指针是指向另一个地址的值。这是教科书上的解释,但如果你转自一门不用谈论变
2023-06-16

Java中ThreadLocal的用法和原理详解

这篇文章主要为大家详细介绍了Java中ThreadLocal的用法和原理,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
2023-05-15

一文彻底了解Java的组合模式

组合模式(Composite Pattern)指将对象组合成树形结构以表示“部分-整体”的层次结构, 使得用户对单个对象和组合对象的使用具有一致性。本文就来带大家深入了解一下Java的组合模式吧
2023-02-24

三张图彻底了解Java中字符串的不变性

该文章是图说Java系列文章中的一篇定义一个字符串String s = "abcd";
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录