早在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中元素的键为线程对象,而值对应线程的变量副本。

Thread同步机制的比较

  ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

  在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

  而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

  由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用,代码清单 9 2就使用了JDK 5.0新的ThreadLocal<T>版本。

  概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

  spring使用ThreadLocal解决线程安全问题我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。

  一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程

  同一线程贯通三层这样你就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。

而总结的博文,总结一句话就是一个是锁机制进行时间换空间,一个是存储拷贝进行空间换时间。

转至http://blog.csdn.net/lufeng20/article/details/24314381

转载于:https://www.cnblogs.com/xinxin-ting/p/7070826.html

ThreadLocal是什么?相关推荐

  1. FastThreadLocal吞吐量居然是ThreadLocal的3倍

    目前关于FastThreadLocal的很多文章都有点老有点过时了(本文将澄清几个误区),很多文章关于FastThreadLocal介绍的也不全,希望本篇文章可以带你彻底理解FastThreadLoc ...

  2. 正确理解ThreadLocal

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt107 首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的, ...

  3. 什么是ThreadLocal

    顾名思义它是local variable(线程局部变量).它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.从线 ...

  4. 为什么jdk源码推荐ThreadLocal使用static

    ThreadLocal是线程私有变量,本身是解决多线程环境线程安全,可以说单线程实际上没必要使用. 既然多线程环境本身不使用static,那么又怎么会线程不安全.所以这个问题本身并不是问题,只是有人没 ...

  5. Spring源码分析【6】-ThreadLocal的使用和源码分析

    Spring代码使用到了ThreadLocal java.lang.ThreadLocal.set getMap java.lang.Thread.threadLocals定义 回到set 如果map ...

  6. threadlocal使用场景_深入剖析ThreadLocal

    点击上方 IT牧场 ,选择 置顶或者星标 技术干货每日送达 朋友们在遇到线程安全问题的时候,大多数情况下可能会使用synchronized关键字,每次只允许一个线程进入锁定的方法或代码块,这样就可以保 ...

  7. ThreadLocal源码分析

    ThreadLocal的作用 Java对象是线程间共享的,但有时我们需要一些线程间隔离的对象,该对象只能由同一个线程读写,对其他线程不可见.ThreadLocal正式提供了这样的机制,详细使用方式请参 ...

  8. ThreadLocal的使用场景

    最近项目中遇到如下的场景:在执行数据迁移时,需要按照用户粒度加锁,因此考虑使用排他锁,迁移工具和业务服务属于两个服务,因此需要使用分布式锁. 我们使用缓存(Tair或者Redis)实现分布式锁,具体代 ...

  9. ThreadLocal的使用方法

    ThreadLocal的含义是Thread Local Variable,它可以声明一个字段,使得不同的线程访问这个字段时,获取的都是不同的副本,互不影响. ThreadLocal的作用和在每个Thr ...

  10. PageHelper 使用 ThreadLocal 的线程复用问题

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://blog.csdn.net/qq_38245668/article/details/105984171/ 前言 ...

最新文章

  1. Spring cloud 微服务docker容器化最佳实践
  2. Camera噪声问题
  3. 【蓝桥java】递归基础之车辆进出栈
  4. R语言readLines函数、n.readLines函数、readline函数读取文本文件实战
  5. 记录一下,以后学Python
  6. 将选定的文本对象左对齐、右对齐或对中
  7. 软件构造第三章 第五部分
  8. php三个数字比较大小排序,php中常用的4种实现数字大小排序的冒泡选择等算法函数代码...
  9. java基础集合数组间的转换(java集合五)
  10. (转)关于数据库存储过程分页DatagridView BindingNavigator 控件的详细实现
  11. 18. GD32F103C8T6入门教程-adc-使用教程5-定时器TIM2更新事件触发adc0
  12. JavaScript 中的垃圾回收和内存泄露如何处理?| 技术头条
  13. visual studio能统计代码规模吗_Windows电脑游戏运行库有必要装吗?
  14. Python 实现单例模式的一些思考
  15. web前端开发面试题(七)
  16. SiamRPN代码分析:test
  17. onlyoffice文档服务器加载慢,【onlyoffice中文指南】12-问题及排除
  18. 雷林鹏最人性化访谈:做投资不仅仅是要赚钱,要成为有价值的人
  19. 十字路口通行优先权,十字路口通行规则图解
  20. java数据类型(java数据类型有哪些)

热门文章

  1. 转: linux 命令行设置网络
  2. c++ include 路径_程序员应如何理解include
  3. grafana 画拓扑图 能不能_Grafana之ImageIt实现动态可感知网络拓扑(第十七篇)
  4. java filter init param_javaweb中的过滤器学习(3)---Filter的部署详细总结
  5. Windows组策略让你的网络系统更强壮
  6. 局域网ip地址不够用怎么解决?
  7. 订单峰值激增 230%,Serverless 如何为世纪联华降本超 40%?|双11 云原生实践
  8. c语言初学者百题大战答案七,C语言百题大战2405how many minutes
  9. 计算机听不到音乐怎么回事,电脑听不到声音怎么解决 电脑听不到声音的处理方法...
  10. 工作流activity_开源、强大的工作流引擎:camunda入门介绍