从ThreadLocal
变量读取多少比常规字段慢?
更具体地说,简单的对象创建比访问ThreadLocal
变量更快还是更慢?
我认为它足够快,因此ThreadLocal<MessageDigest>
实例比MessageDigest
每次创建实例要快得多.但这也适用于字节[10]或字节[1000]吗?
编辑:问题是在调用ThreadLocal
get 时真正发生的事情?如果那只是一个领域,就像任何其他领域一样,那么答案就是"它总是最快",对吧?
我知道PC-Lint可以告诉你包含但未使用的标题.有没有其他工具可以做到这一点,最好是在Linux上?
我们拥有一个庞大的代码库,在过去的15年中已经看到了大量的功能,但是当功能从一个实现文件移动到另一个实现文件时,很少会删除剩余的#include指令,这一点让我们陷入了相当糟糕的状态.显然我可以去除所有#include指令并让编译器告诉我哪些重新包含,但是我宁愿反过来解决问题 - 找到未使用的指令 - 而不是重建已使用的指令列表.
我正在使用线程本地来存储当前用户和请求对象.通过这种方式,我可以轻松访问程序中任何位置的请求(例如动态表单),而无需传递它们.
为了在中间件中实现线程本地存储,我遵循了Django站点上的教程:http: //code.djangoproject.com/wiki/CookBookThreadlocalsAndUser?version = 18
此文档已经过修改,建议避免使用此技术:http: //code.djangoproject.com/wiki/CookBookThreadlocalsAndUser?version = 20
来自文章:
从设计的角度来看,threadlocals本质上是全局变量,并且受到全局变量通常需要的所有常见的可移植性和可预测性问题的影响.
更重要的是,从安全角度来看,threadlocals构成了巨大的风险.通过提供公开其他线程状态的数据存储,您可以为Web服务器中的一个线程提供一种方法来潜在地修改系统中另一个线程的状态.如果线程本地数据包含用户或其他与身份验证相关的数据的描述,则该数据可以用作授予对未授权用户的访问权的攻击的基础,或者暴露用户的私有细节.虽然有可能建立一个可以抵御这种攻击的线程局域系统,但是防御起来要容易得多,并且建立一个不受任何此类漏洞影响的系统.
我理解为什么全局变量可能很糟糕,但在这种情况下,我在自己的服务器上运行自己的代码,所以我看不出两个全局变量带来的危险.
有人可以解释涉及的安全问题吗?我问过很多人,如果他们阅读这篇文章并知道我正在使用线程本地人,他们会如何破解我的应用程序,但没有人能告诉我.我开始怀疑这是一个由分裂的纯粹主义者所持的观点,他们喜欢明确地传递物品.
当我阅读scalatra的来源时,我发现有一些代码如下:
protected val _response = new DynamicVariable[HttpServletResponse](null)
protected val _request = new DynamicVariable[HttpServletRequest](null)
Run Code Online (Sandbox Code Playgroud)
有一个有趣的课程名称DynamicVariable
.我看过这堂课的文件,但我不知道何时以及为什么要使用它?它有一个withValue()
通常使用的.
如果我们不使用它,那么我们应该使用什么代码来解决它解决的问题?
(我是scala的新手,如果你能提供一些代码,那就太好了)
据我所知,Servlet 3规范引入了异步处理功能.除此之外,这意味着可以并且将重用相同的线程来处理另一个并发的HTTP请求.这不是革命性的,至少对于之前与NIO合作的人来说至少是这样.
无论如何,这导致另一个重要的事情:没有ThreadLocal
变量作为请求数据的临时存储.因为如果同一个线程突然成为另一个HTTP请求的运营商线程,请求本地数据将暴露给另一个请求.
所有这些都是基于阅读文章的纯粹推测,我没有时间玩任何Servlet 3实现(Tomcat 7,GlassFish 3.0.X等).
所以,问题:
ThreadLocal
将不再是一个方便的黑客来保存请求数据?ThreadLocal
s来证明上述内容?编辑:别误会我的意思.我完全理解危险并ThreadLocal
成为黑客.事实上,我总是建议不要在类似的环境中使用它.但是,不管你信不信,线程上下文的使用频率比你想象的要频繁得多.一个很好的例子是Spring的OpenSessionInViewFilter
,根据它的Javadoc:
此过滤器通过当前线程使Hibernate会话可用,该线程将由事务管理器自动检测.
这不是严格的ThreadLocal
(没有检查来源),但已经听起来令人震惊.我可以想到更多类似的场景,而且丰富的Web框架使得这种情况更有可能发生.
简而言之,许多人在这个黑客的基础上建造了他们的沙堡,无论是否有意识.因此,斯蒂芬的答案是可以理解的,但并不完全是我所追求的.我想得到一个确认是否有人真正尝试并能够重现失败的行为,所以这个问题可以作为被同一问题困扰的其他人的参考点.
当你使用a ThreadLocal<T>
和T实现IDisposable时,你应该如何处理ThreadLocal中的成员?
根据ILSpy,ThreadLocal的Dispose()和Dispose(bool)方法是
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
int currentInstanceIndex = this.m_currentInstanceIndex;
if (currentInstanceIndex > -1 && Interlocked.CompareExchange(ref this.m_currentInstanceIndex, -1, currentInstanceIndex) == currentInstanceIndex)
{
ThreadLocal<T>.s_availableIndices.Push(currentInstanceIndex);
}
this.m_holder = null;
}
Run Code Online (Sandbox Code Playgroud)
ThreadLocal似乎没有尝试在其子成员上调用Dispose.我不知道如何引用它内部分配的每个线程,所以我可以处理它.
我使用以下代码运行测试,该类从未处理过
static class Sandbox
{
static void Main()
{
ThreadLocal<TestClass> test = new ThreadLocal<TestClass>();
test.Value = new TestClass();
test.Dispose();
Console.Read();
}
}
class TestClass : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool Disposing)
{
Console.Write("I …
Run Code Online (Sandbox Code Playgroud) 每个人都在Django世界似乎恨threadlocals(http://code.djangoproject.com/ticket/4280,http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser).我读过Armin的论文(http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others),但大多数都取决于threadlocals是坏的,因为它是不雅.
我有一个场景,其中thellocals将使事情变得更加容易.(我有一个应用程序,人们将有子域名,因此所有模型都需要访问当前子域名,并且从请求中传递它们是不值得的,如果threadlocals的唯一问题是它们不优雅,或者变得脆弱码.)
许多Java框架似乎也经常使用threadlocals,那么他们的情况与Python/Django的情况有何不同?
我ThreadLocal
在我的网络应用程序中填充了几个.而且,在远程调试webapp时,我希望看到这些ThreadLocal
变量的值Eclipse
(就像Eclipse
在Debug透视图中的变量选项卡中显示其他变量一样).
任何想法如何ThreadLocal
在调试过程中查看变量的值Eclipse
?
谢谢!
我正在研究和试验我的Java Web应用程序中的ThreadLocal变量.我使用ThreadLocal变量在请求之前存储用户名(从会话中收集),然后在请求后删除它.我通过在ServletFilter中调用静态实用程序方法来完成此操作.我不是简单地从会话中检索用户名的原因是因为我继承了一个系统,该系统具有长时间运行的进程,有时需要比会话超时允许的运行时间更长.我的想法是在处理请求之前获取用户名并将其存储在ThreadLocal变量中,这样我就可以在整个请求期间访问用户名,即使它花费的时间超过15分钟.
我的问题是:
这种设计是否存在任何安全/性能问题?如果有,那么什么是更好的解决方案?即使没有任何安全和/或性能问题,也欢迎更好的想法.我的解决方案中的代码段如下所示:
这是我的实用程序类,将在我的过滤器和我需要用户名的任何地方调用.
public abstract class UserUtil {
private static final ThreadLocal<String> threadUser = new ThreadLocal<String>();
public static String getUserId(){
return threadUser.get();
}
public static void setUserId(String userId){
threadUser.set(userId);
}
public static void removeUserId(){
threadUser.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的servlet过滤器,用于在请求之前设置用户名(并在请求后通过finally块清除它).
public class UserFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
HttpServletRequest request = (HttpServletRequest) servletRequest;
UserBean userBean …
Run Code Online (Sandbox Code Playgroud) thread-local ×8
java ×4
django ×2
python ×2
.net-4.0 ×1
amqp ×1
api ×1
c# ×1
c++ ×1
coding-style ×1
debugging ×1
eclipse ×1
header-files ×1
idisposable ×1
json ×1
performance ×1
rpc ×1
scala ×1
servlet-3.0 ×1
servlets ×1
session ×1