它将很好地启动。 像大多数故事一样。 您会发现一个新概念,并对其功能感到惊讶。 然后突然装备了这把新锤子,一切开始看起来像钉子。 根据我们过去几个月的经验, java.lang.ThreadLocal真是一锤定音。

我想这全都归结为ThreadLocal的工作原理。 通过范围界定类推最容易理解这个概念。 以同样的方式,您的Spring Bean可以处于容器,会话或请求范围内。 ThreadLocal使您可以在Thread范围内声明对象。

您可以将任何对象设置为ThreadLocal,并且该对象在访问该对象的线程中将具有全局作用域和局部作用域。 首先可能会很复杂,但让我解释一下:

  • 线程可以全局访问ThreadLocal中存储的值。 这意味着,如果您可以访问代码中的ThreadLocal引用,则可以从该线程内部的任何位置访问其中存储的值。 如果线程从多个类调用方法,则所有方法都可以看到其他方法设置的ThreadLocal变量(因为它们在同一线程中执行)。 该值无需显式传递。 就像使用全局变量一样。
  • 存储在ThreadLocal中的值是线程本地的,这意味着每个线程将拥有自己的ThreadLocal变量。 一个线程无法访问/修改其他线程的ThreadLocal变量。

因此,在这里我们有一个值得庆祝的理由–我们手中有一个真正强大的概念。 这通常是呈现有状态类线程安全的最简单方法。 并封装非线程安全类,以便可以在多线程环境中安全地使用它们。 除了简单之外,使用ThreadLocal存储每个线程单个信息或每个线程上下文信息还包含有价值的信息–通过使用ThreadLocal ,很明显,线程之间不共享存储在ThreadLocal中的对象,从而简化了任务确定类是否是线程安全的。 当您手头有1,000,000行的代码库时,我们发现这并非易事。

另一方面,这个强大的概念在错误的手中会产生许多问题。 像其他任何滥用的设计概念一样。 在过去的几个月中,我们最经常遇到两个问题:

  • ThreadLocal使您可以使用变量,而无需在方法调用链中显式传递它们。 在某些情况下可能有用。 但是你们那里创建了n层体系结构以抽象出不同的通信接口的人们。 然后从您的DAO对象中的ThreadLocals中获取HttpServletRequest ……您在做这个决定时在吸烟吗? 我们在研究这个特定案例时花了几个小时和第二双眼睛。 但是无论如何-使用全球化的力量时要小心。 您最终在代码中创建了意外的依赖关系。 您可能还记得–这不是明智的选择。
  • 使用ThreadLocal时,很容易在代码中引入内存泄漏。 这很好地说明了类加载器周围的复杂性。 如果要在应用程序服务器中部署代码,则将使用与应用程序服务器本身使用的类加载器不同的类加载器加载/卸载应用程序类。 这本身还不错。 但是,现在考虑到现代应用程序服务器也池化线程,而不是在每个HttpRequest上创建一个新线程,我们为问题奠定了基础。

如果其中一个应用程序类将一个值存储在ThreadLocal变量中,并且在手头的任务完成后没有将其删除,则该Object的副本将与Thread一起保留(来自应用程序服务器线程池)。 由于池化线程的寿命超过了应用程序的寿命,因此它将防止该对象,从而使ClassLoader负责加载应用程序而不会被垃圾回收。 而且我们创建了一个泄漏,有机会以一种很好的旧java.lang.OutOfMemoryError:PermGen空间形式浮出水面。

因此,考虑到它可能造成的危害,我们应该避免使用ThreadLocal吗? 约书亚·布洛赫(Joshua Bloch)十年前曾说过:

“您是否可以通过线程局部变量导致意外的对象保留? 你当然可以。 但是您也可以使用数组来执行此操作。 这并不意味着线程局部变量(或数组)是坏事。 只是您必须谨慎使用它们。 使用线程池需要格外小心。 随意使用线程池与随意使用线程本地变量相结合会导致意外的对象保留,这在许多地方都已提到。 但是,将责任归咎于线程本机是没有根据的。”

我倾向于同意布洛赫先生的观点,并且不认为ThreadLocal是邪恶的创造。 但是我也确实认为这是许多人无法正确理解的概念。

本文的灵感主要收集在寻找一些令人讨厌的错误的不眠之夜中。 但是在写作时,以下资源也被证明是有益的:

  • Veera Sundar 博客文章解释了范围界定
  • Javin Paul关于ThreadLocal泄漏的摘要
  • Joshua Bloch对ThreadLocals的看法

参考: 如何与我们的JCG合作伙伴 Nikita Salnikov Tarnovski (来自Plumbr Blog博客) 一起使用ThreadLocals进行射击 。

翻译自: https://www.javacodegeeks.com/2013/01/how-to-shoot-yourself-in-foot-with-threadlocals.html

如何用ThreadLocals射击自己相关推荐

  1. threadlocals_如何使用ThreadLocals射击自己

    threadlocals 它将很好地启动. 像大多数故事一样. 您会发现一个新概念,并对其功能感到惊讶. 然后突然装备了这把新锤子,一切开始看起来像钉子. 根据我们过去几个月的经验, java.lan ...

  2. java 并发 线程安全_Java并发教程–线程安全设计

    java 并发 线程安全 在回顾了处理并发程序时的主要风险(例如原子性或可见性 )之后,我们将通过一些类设计来帮助我们防止上述错误. 其中一些设计导致了线程安全对象的构造,从而使我们能够在线程之间安全 ...

  3. sun.misc.Unsafe苦难告诉我们什么

    Oracle将删除Java 9中的内部sun.misc.Unsafe类 . 尽管大多数人可能对这种变化漠不关心,但其他一些人(主要是图书馆开发人员)并非如此. 博客圈中最近有几篇文章描绘了这种变化所暗 ...

  4. SMB签名的基础知识(同时覆盖SMB1和SMB2)

    SMB签名概述 服务器消息块(SMB)是Windows最常用的文件协议.SMB签名是一项功能,通过它可以在数据包级别对使用SMB的通信进行数字签名.对数据包进行数字签名可以使数据包的接收者确认其来源和 ...

  5. 用visio画用例图小人_教你如何用 Python 打飞机 ?

    前言:python 除了生孩子 ,啥都会 .包括打飞机 !今天就来教你如何用 python 打飞机 ! 简述 相信你是一个单纯的孩子说的打飞机是指啥意思 ,对吧 ?嗯 ,没毛病 .就是 pygame ...

  6. python打飞机源代码-如何用 Python 打飞机 ?

    前言:python 除了生孩子 ,啥都会 .包括打飞机 !今天小詹的一位读者就来教你如何用 python 打飞机 ! 简述 相信小詹是一个单纯的孩子 ,也相信大家明白小詹说的打飞机是指啥意思 ,对吧 ...

  7. web网页设计——体育气步枪射击主题(5页面)带图片轮播特效(HTML+CSS) ~学生网页设计作业源码

    web网页设计--体育气步枪射击主题(5页面)带图片轮播特效(HTML+CSS) ~学生网页设计作业源码 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手 ...

  8. unity第三人称射击游戏_在游戏上第3部分完美的信息游戏

    unity第三人称射击游戏 Previous article 上一篇文章 The economics literature distinguishes the quality of a game's ...

  9. [Unity]《太空射击》开发日记Ep.2(初级篇)

    文章目录 前言 敌人1脚本 预制件 敌人1的完善工作 触发器式碰撞 屏幕边缘检测 计算敌人1的飞行角度 优化敌人生成器 前言 [Unity]<太空射击>开发日记Ep.1(入门篇) 在上一篇 ...

最新文章

  1. R语言构建决策树(decision trees)模型并进行调优和解释
  2. ubuntu 12.04 交叉编译 arm/mips 平台的 strace
  3. 1.12 foreach循环遍历Collection集合
  4. boost::gil模块数字扩展中的 resize_view() 示例
  5. SQL Server表分区
  6. python笔记之function函数
  7. 学堂在线计算机挂了咋办,各位师兄师姐我想问下计算机挂了是直接重修吗(#泪)...
  8. c语言宿舍管理设计报告,C语言课程设计—学生宿舍管理系统设计报告.doc
  9. java操作Excel之POI(4)利用POI实现数据的批量导出
  10. 标准C程序设计七---05
  11. 《健康流言终结者》一句话总结
  12. MySQL集群安装与配置
  13. Tomcat下载——tomcat7、tomcat8、tomcat9官网下载链接
  14. 维修涉及行业2021-11-15
  15. 2021全网影视APP搭建教程全套完整版
  16. PS如何去除图片中文字
  17. 二级域名映射服务器,如何进行二级域名解析做端口映射?
  18. ffmpeg 双轨的mp3转成8k的wav 脚本
  19. 如何批量去除视频水印教程
  20. OneFlow源码解析:静态图与运行时

热门文章

  1. es6 dsl与sql对比
  2. spring react_使用Spring WebFlux构建React性REST API –第1部分
  3. jpa执行sql脚本_JPA persistence.xml SQL脚本定义
  4. java 交替_Java 8:使用交替接口公开的类型安全地图生成器
  5. java ee 下版本_将旧版本从Java EE 5减少到7
  6. perl大骆驼和小骆驼_快速的骆驼和云消息传递
  7. 战神4 幕后花絮 概念艺术_Java 9幕后花絮:新功能从何而来?
  8. 用Rocker制作模板
  9. 无状态会话的ejb_Java EE状态会话Bean(EJB)示例
  10. 高级java开发_适用于高级Java开发人员的十大书籍