如何用ThreadLocals射击自己

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

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

Shoot 您可以将任何对象设置为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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

确保任务的执行顺序

有时有必要对线程池中的任务施加一定的顺序。 JavaSpecialists通讯的第206期提出了一种这样的情况:我们有多个连接,使用NIO可以从中读取。 我们需要确保给定连接中的事件按顺序执行,但是不同连接之间的事件可以自由混合。 我想提出一个类似但…

transition

一、语法 transition: property duration timing-function delay transition属性是个复合属性,她包括以下几个子属性: transition-property :规定设置过渡效果的css属性名称transition-duration :规定完成过渡效果需要多少秒或…

图解在VC里使用graphics.h画图(相似TC)

1 www.easyx.cn 下载 EasyX 库 我下的2014;解压后例如以下图&#xff1b; 2 依据自己的VC 版本号进行安装 3 在控制台画一个圆 #include <graphics.h> // 引用图形库 #include <conio.h> void main() {initgraph(640, 480); // 初始化画图窗体circle(200, 200, 100…

使用SwingWorker的Java Swing中的多线程

如果要使用Swing用J​​ava编写桌面或Java Web Start程序&#xff0c;您可能会觉得需要通过创建自己的线程在后台运行某些东西。 没有什么可以阻止您在Swing中使用标准的多线程技术&#xff0c;并且需要遵循通常的注意事项。 如果您有多个线程访问相同的变量&#xff0c;则需要…

MySql Jar 包下载

MySql JAR 包下载 我们要使用Spring 链接MySql 需要两个Jar 包 一个是C3p0 一个是MySql 的Connection Jar 包 C3p0&#xff1a; 进入下面的网址 http://www.mchange.com/projects/c3p0/ 按照黄色的指示 下载 2. MySql Jar 包 进入MySql 官网 https://dev.mysql.com/down…

c语言以空格分割字符串_c语言中,输入任意字符串,任意空格隔开

c语言中,输入任意字符串,任意空格隔开关注:132 答案:3 mip版解决时间 2021-01-27 16:01提问者更无风月2021-01-27 01:51如题,希望大神代码最佳答案二级知识专家闪光的男人2021-01-27 02:50用scanf以%s读入字符串&#xff0c;即可实现输入以空格分隔的字符串。以下代码功能为&…

Unity经典游戏教程之:是男人就下100层

版权声明&#xff1a; 本文原创发布于博客园"优梦创客"的博客空间&#xff08;网址&#xff1a;http://www.cnblogs.com/raymondking123/&#xff09;以及微信公众号"优梦创客"&#xff08;微信号&#xff1a;unitymaker&#xff09;您可以自由转载&#x…

Html和websocket初识

一、web框架 众所周知&#xff0c;对于所有的Web应用&#xff0c;本质上其实就是一个socket服务端&#xff0c;用户的浏览器其实就是一个socket客户端。 import socketdef handle_request(client):buf client.recv(1024)client.send(b"HTTP/1.1 200 OK\r\n\r\n")cli…

java lombok 视频_Java开发神器Lombok使用详解

最近正在写SpringBoot系列文章和录制视频教程&#xff0c;每次都要重复写一些Getter/Setter、构造器方法、字符串输出的ToString方法和Equals/HashCode方法等。甚是浪费时间&#xff0c;也影响代码的可读性。因此&#xff0c;今天就给大家推荐一款Java开发神器——Lombok&#…

11-[函数进阶]-闭包

1.什么是闭包&#xff1f; 内部函数对外部函数作用域里变量的引用&#xff08;非全局变量&#xff09;&#xff0c;则称内部函数为闭包。 def outer():n 10def inner():print("inner:", n)return innerval outer() print(val) val() 闭包的意义&#xff1a;返回的…

CSS实现单行、多行文本溢出显示省略号(…)

如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来&#xff0c;当然还需要加宽度width属来兼容部分浏览。 实现方法&#xff1a; overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 效果如图&#xff1a; 但是这个属性只支持单行…

显示日历的指令:cal

1.显示日历的指令&#xff1a;cal &#xff08;1&#xff09;参数&#xff1a; &#xff08;2&#xff09;实例&#xff1a; 转载于:https://www.cnblogs.com/yfacesclub/p/8434449.html

简单好用的计算器:bc

1.简单好用的计算器&#xff1a;bc &#xff08;1&#xff09;参数&#xff1a; &#xff08;2&#xff09;实例&#xff1a; 执行浮点运算和一些高级函数 设定小数精度&#xff08;数值范围&#xff09; 进制转换 执行结果为&#xff1a;11000000&#xff0c;这是用bc将十进制…

block,inline,inline-block的区别

最近正在复习&#xff0c;紧张地准备几天后的笔试&#xff0c;然后刚好看到这个地方。 block&#xff1a;块级元素&#xff0c;会换行&#xff0c;如div,p,h1~h6,table这些&#xff0c;可以设置宽高&#xff1b; inline:行内元素&#xff0c;不换行&#xff0c;挤在一行显示&am…

anyproxy抓取移动http、https请求

windows下安装AnyProxy抓取移动App Http请求AnyProxy是阿里巴巴基于 Node.js 开发的一款开源代理服务器。做为中间代理服务器&#xff0c;它可以收集所有经过它的http请求流量&#xff08;包括https明文内容&#xff09;&#xff1b;它提供了友好的web界面&#xff0c;便于直观…

Windows 10 IoT Core 17101 for Insider 版本更新

除夕夜&#xff0c;微软发布了Windows 10 IoT Core 17101 for Insider 版本更新&#xff0c;本次更新只修正了一些Bug&#xff0c;没有发布新的特性。已知的问题: F5 driver deployment from Visual Studio does not work on IoT Core.F5 application deployment of headed f…

Spring Batch中的块处理

大数据集的处理是软件世界中最重要的问题之一。 Spring Batch是一个轻量级且强大的批处理框架&#xff0c;用于处理数据集。 Spring Batch Framework提供了“面向TaskletStep”和“面向块”的处理风格。 在本文中&#xff0c;将解释面向块的处理模型。 此外&#xff0c;绝对建…

type=file文件上传H5新特性

1、语法 <input name"myFile" type"file"> 2、属性&#xff08;以下三个仅 HTML5支持&#xff0c;因此存在兼容性问题&#xff09;&#xff08;1&#xff09;multiple &#xff1a;表示用户是否可以选择多个值。multiple只能用于typefile和typeemail…

epoll学习

一、epoll_create #include <sys/epoll.h>int epoll_create(int size); int epoll_create1(int flags); 返回&#xff1a;成功非负文件描述符&#xff0c;-1出错size:内核监听数目一共多大 创建一个epoll接口&#xff0c;size参数和select不同&#xff0c;不是fd1&#x…