线程故事:Web应用程序中的ThreadLocal

本周,我花了一些合理的时间来消除Web应用程序中的所有ThreadLocal变量。 原因是他们造成了类加载器泄漏,我们不能再适当地取消部署我们的应用程序。 取消部署应用程序后,当GC根目录继续引用应用程序对象时,将发生类加载器泄漏。 如果取消部署后仍引用了应用程序对象,则无法对整个类加载器进行垃圾回收,因为考虑的对象引用了您的应用程序类文件,而应用程序类文件又引用了类加载器。 取消部署和重新部署几次后,这将导致OutOfMemoryError

ThreadLocal是一种经典的候选人,可以轻松在Web应用程序中创建类加载器泄漏。 服务器正在管理池中的线程。 这些线程的寿命比您的Web应用程序更长。 实际上,直到底层JVM死亡,它们才完全消失。 现在,如果将ThreadLocal放入引用类的对象的池线程中,则必须*小心。 您需要确保使用ThreadLocal.remove()再次删除此变量。 Web应用程序中的问题是:安全删除ThreadLocal变量的正确位置在哪里? 此外,您可能不想每次同事决定将另一个ThreadLocal添加到托管线程时都修改该“删除代码”。

我们围绕线程局部开发了一个包装器类,该类将所有线程局部变量保留在一个单独的ThreadLocal变量中。 这是代码。

public class ThreadLocalUtil {private final static ThreadLocal<ThreadVariables> THREAD_VARIABLES = new ThreadLocal<ThreadVariables>() {/*** @see java.lang.ThreadLocal#initialValue()*/@Overrideprotected ThreadVariables initialValue() {return new ThreadVariables();}};public static Object getThreadVariable(String name) {return THREAD_VARIABLES.get().get(name);}public static Object getThreadVariable(String name, InitialValue initialValue) {Object o = THREAD_VARIABLES.get().get(name);if (o == null) { THREAD_VARIABLES.get().put(name, initialValue.create());return getThreadVariable(name);} else {return o;}}public static void setThreadVariable(String name, Object value) {THREAD_VARIABLES.get().put(name, value);}public static void destroy() {THREAD_VARIABLES.remove();}
}public class ThreadVariables extends HashMap<String, Object> { }public abstract class InitialValue {public abstract Object create();}

实用程序类的优点是无需开发人员就可以单独管理线程局部变量的生命周期。 该类将所有线程局部变量放在一个变量映射中。 可以调用destroy()方法,在其中可以安全地删除Web应用程序中的所有线程本机。 在我们的例子中,这就是ServletRequestListener -> requestDestroyed()方法。 您还需要将finally块放置在其他位置。 典型的地方是HttpServletinit()doPost()doGet()方法附近。 完成请求或意外引发异常后,这可能会删除池工作线程中的所有线程本地。 有时会发生服务器的main线程泄漏线程局部变量的情况。 如果是这种情况,则需要找到正确的位置来调用ThreadLocalUtil -> destroy()方法。 为此,要弄清楚主线程实际上在哪里创建线程变量。 您可以使用调试器来做到这一点。

许多人建议出于多种原因而在Web应用程序中省略ThreadLocal 。 在池化线程环境中删除它们可能非常困难,以便您可以安全地取消部署应用程序。 ThreadLocal变量可能有用,但是在应用它们之前考虑其他技术是很公平的。 Web应用程序可以携带请求范围参数的替代方法是HttpServletRequest 。 许多Web框架允许通用的请求参数访问以及请求/会话属性访问,而无需与本地Servlet / Portlet API绑定。 同样,许多框架支持请求使用依赖项注入将作用域Bean注入到对象树中。 所有这些选项都满足大多数要求,因此在使用ThreadLocal之前应考虑这些选项。

参考:线程故事: JCG合作伙伴 Niklas的Web应用程序中的ThreadLocal。


翻译自: https://www.javacodegeeks.com/2012/05/threading-stories-threadlocal-in-web.html

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

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

相关文章

n-1位数

n-1位数 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;1描述已知w是一个大于10但不大于1000000的无符号整数&#xff0c;若w是n(n≥2)位的整数&#xff0c;则求出w的后n-1位的数。 输入第一行为M&#xff0c;表示测试数据组数。接下来M行&…

Android之封装好的异步网络请求框架

1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnection&#xff0c;但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求&#xff0c;而使用这个MyHttpUtils库可以大大的简化操作&#xff0c;它是基于HttpURLConnection&#xff0c;所有…

华润置地php面试题_从一流到顶流|2020华润置地与沈阳一起美好

如果用一句话来形容华润置地进入沈阳13年的发展历程&#xff0c;你认为是什么&#xff1f;“从优秀到卓越”。用2020年的语言你给我翻译一下&#xff1f;“从一流到顶流”&#xff01;01/ 初识的美好犹记2007年1月&#xff0c;央企华润置地首进沈阳&#xff0c;在大馆原址呈现出…

金融工作用计算机吗,为什么计算机专业的人想转金融,而金融专业的想转计算机?...

1首先两个专业都很有前途。如果好好学IT&#xff0c;应该是走技术路线&#xff0c;30岁后逐渐开始搞些管理或者设计之类的。当然&#xff0c;继续搞技术也没问题。只是要不断学习&#xff0c;因为发展很快&#xff0c;IT业自身不断更新。很多人说IT枯燥&#xff0c;难学&#x…

Java GUI应用程序关闭陷阱

最近&#xff0c;我遇到了一个或两个Java GUI应用程序在关闭时无法关闭的问题。 它们似乎是一个过程&#xff0c;消耗着计算机资源。 今天&#xff0c;我深入探究了问题的根源&#xff0c;这是一个我以前从未意识到的棘手问题&#xff0c;所以我想我会分享一下。 理论上&#x…

shell启动程序脚本

#!/bin/bash#/usr/local/xxx/bin/xxxx.sh start#/usr/local/xxx/bin/startup.shfor i in find /server -name start.sh do fadirdirname $i //读取父目录 cd $fadir echo > nohup.out ./start.sh & sleep 2 echo "start succe…

Unity性能优化的N种武器

贴图&#xff1a; l 控制贴图大小&#xff0c;尽量不要超过 1024 x1024&#xff1b; l 尽量使用2的n次幂大小的贴图&#xff0c;否则GfxDriver里会有2份贴图&#xff1b; l 尽量使用压缩格式减小贴图大小&#xff1b; l 若干种贴图合并技术&#xff1b; l 去除多余的alpha…

cmd控制屏幕光标_电脑控制手机?上班时间愉快尽情地玩手机吧!它值得您拥有!...

在现今时代&#xff0c;手机已成为人们必不可少的工具&#xff0c;有的时候甚至可以说手机比电脑方便好用多了&#xff0c;例如某些实用的APP软件就只有手机端并没有电脑端&#xff0c;想使用的话就得整天捧着手机盯着不放。但别忘记&#xff0c;我们大多数都是打工族&#xff…

xp系统设置锁定计算机,系统锁定时不关机的诀窍 给XP系统关闭计算机再加一把锁...

很多用户抱怨在使用电脑的过程中&#xff0c;总是经常会被琐碎的事情打断&#xff0c;有时候难免暂时离开电脑&#xff0c;处于便利和资料安全&#xff0c;我们往往会按下“WindowsL”来锁定计算机。这样&#xff0c;操作方便同时又能阻止他人乱动我们的计算机。但是如果遇到好…

ACM题目————中位数

题目描述 长为L的升序序列S&#xff0c;S[L / 2]为其中位数。 给出两个等长升序序列S1和S2&#xff0c;求两序列合并并排序后的中位数。 输入 多组数据&#xff0c;每组第一行为n&#xff0c;表示两个等长升序序列的长度。 接下来n行为升序序列S1的元素&#xff0c;再接下来n行…

Regular Exprassion--正则表达式基础

正则表达式&#xff1a; 强大灵活的文本处理工具 语法&#xff1a; 普通字符 转义字符 \ , \t , \n , \\ 标准字符集合&#xff08;大写代表相反的意思&#xff09; \d 任意一个数字 \w 任意一个字母、数字、下划线 \s 空白符&#xff…

使用ReportNG更好看的TestNG HTML测试报告– Maven指南

当“扩展TestCase”是编写测试中必不可少的一部分时&#xff0c; TestNG是作为JUnit 3的注释驱动替代创建的测试框架。 即使现在&#xff0c;它也提供了一些有趣的功能&#xff0c;例如数据提供程序&#xff0c;并行测试或测试组。 在我们的测试不是从IDE执行的情况下&#xff…

gitee项目404问题_七款开源项目,让你数据库管理不再成为一个问题

在开发过程中&#xff0c;数据库是必不可少的一环&#xff0c;但大多数情况下开发者们还是在用命令行来管理数据库。虽然在外人看起来输入一行行代码非常的酷炫&#xff0c;但其中的繁琐可能也只有开发者知道。七款开源项目&#xff0c;让你数据库管理不再成为一个问题今天 Git…

vb 窗体html表格,VB.Net – 高级表格

在本章中&#xff0c;让我们研究以下概念 :在应用程序中添加菜单和子菜单在表单中添加剪切&#xff0c;复制和粘贴功能锚定和对接控件表格模态表格添加菜单和子菜单应用程序中的菜单传统上&#xff0c;菜单&#xff0c;MainMenu&#xff0c;ContextMenu和MenuItem类用于在Windo…

SpringMVC后台接收list类型的数据的实现方式

一、背景 最近在做一些东西的时候&#xff0c;遇到一个需要Springmvc后台接收list类型数据的需求&#xff0c;几经辗转才完美解决了这个问题&#xff0c;今天记下来方便以后使用&#xff0c;也分享给需要的小伙伴们~ 二、实现方式 实现方式一 前端页面 1 <% page language&q…

Maven集成测试和Spring Restful Services

介绍 我的原始博客通过一个非常简单的示例展示了如何分离Maven单元和集成测试。 http://johndobie.blogspot.com/2011/06/seperating-maven-unit-integration-tests.html此后&#xff0c;许多人要求我提供比最初使用的示例更实际的示例。 这篇文章展示了如何在实际环境中&#…

玩cf出现outofmemory_CF画质粗糙平衡感人,却能历经十年经久不衰,靠的是什么?...

Hello大家好&#xff0c;我是沐辰。《穿越火线》这款游戏国内运营时间已长达十年&#xff0c;从最早接触这款游戏开始&#xff0c;很多玩家都在这里烙刻下了许多关于青春的回忆。CF的许多问题一直颇受诟病&#xff0c;例如落后且粗糙的画质、英雄级武器与平民武器的巨大差距、千…

jquery遍历ajax返回的json数据

我们以前在前端遍历ajax拿到的数据一般都是用for或其他方式遍历&#xff0c;这样做麻烦且费事&#xff0c;效率不高&#xff0c;下面提供一个函数&#xff0c;只需调用函数即可把数据遍历出来&#xff0c;方便高效。 html代码&#xff1a; <html> <head><script…

Apache JMeter:随心所欲进行负载测试

这是有关使用Apache JMeter进行负载测试的第二篇文章&#xff0c;请在此处阅读第一篇文章&#xff1a; 有关对关系数据库进行负载测试的分步教程。 JMeter有很多采样器 。 如果您需要JMeter不提供的采样器&#xff0c;则可以编写自定义采样器。 &#xff08;自定义采样器在JMet…

html5历史管理

在网易云课堂上看了妙味课堂的关于html5历史管理的课程&#xff0c;在这里做一下笔记。 单页面或ajax局部刷新的页面中&#xff0c;没有办法通过前一步和后一步得到历史访问数据&#xff0c;此时有两种方法可以解决这个问题&#xff1a; 1.onhashchange事件&#xff0c;示例代码…