ThreadLocal是如何实现的?它是用Java实现的(使用从ThreadID到对象的一些并发映射),还是使用一些JVM钩子来更有效地执行它?
我有一些代码,我在C#中使用线程静态对象.
[ThreadStatic]
private DataContext connection
Run Code Online (Sandbox Code Playgroud)
我想知道,在这种情况下,如果我将静态修饰符放在线程静态上下文中,我会得到什么改变?
[ThreadStatic]
private static DataContext connection
Run Code Online (Sandbox Code Playgroud)
第一个是每个线程每个实例有一个上下文副本,每个线程只有一个副本吗?
我正在使用ThreadStatic变量来存储一些数据,但是我担心在完成它并释放回ThreadPool后,我在线程上存储的数据仍然存在.在完成线程之前,我是否需要担心清除ThreadStatic变量?或者ThreadPool会在为下一个QueueUserWorkItem"传递出去"之前为我做这个吗?这对我来说尤其重要,因为我需要确保我的应用程序中的其他线程有一个干净的平板可以使用ThreadStatic变量.谢谢!
[ThreadStatic]
private static Foo _foo;
public static Foo CurrentFoo {
get {
if (_foo == null) {
_foo = new Foo();
}
return _foo;
}
}
以前的代码线程安全吗?或者我们需要锁定方法吗?
该ThreadStatic属性声明静态变量作为独特的,每个线程.你知道一个简单的模式来正确处理这些变量吗?
我们在ThreadStatic之前使用的是ThreadContextManager.每个线程都分配了一个ThreadContext,它保留了所有特定于线程的信息.我们产生了一些线程并让它们工作.然后,当它们全部完成时,我们处理了ThreadContentManager,如果它们是IDisposable,它们会处理所有上下文.
我没有看到将此模式转换为ThreadStatic对象的直接方法.最终将丢弃对象,因为线程会死亡,因此没有任何引用它们.但是,我们更倾向于确定性处置.
更新
我没有直接控制线程 - 我正在使用Microsoft CCR,它有一个执行任务的ThreadPool.当所有任务完成后,我正在处理Dispatcher(它拥有线程池).问题是 - 我没有机会在线程的主要功能结束时做任何事情" - 所以我不能在线程运行结束时手动处理事情.我能以某种方式从线程外部访问线程的静态对象吗?
我正在大量使用Parallel Extensions,我刚刚遇到一种情况,即使用线程本地存储可能是合理的,允许工作线程重用对象.因此,我查看了ThreadStatic属性,该属性将静态字段/变量标记为每个线程具有唯一值.
在我看来,使用PE与ThreadStatic属性是不明智的,而不保证PE重用线程.也就是说,如果在某种程度上创建和销毁线程,那么变量(以及它们指向的对象)是否会在线程本地存储中保留一段不确定的时间,从而导致内存泄漏?或者线程存储可能与线程相关联并在线程处理时被丢弃?但是,您仍然可能在池中存在长期存在的线程,并且会从线程所使用的各种代码中累积线程本地存储.
是否有更好的方法来获取PE的线程本地存储?
谢谢.
首先,我希望基于上下文的存储在整个框架中保持一致!
话虽如此,我正在寻找一种优雅的解决方案,使这些属性在ASP.NET,WCF和任何其他多线程.NET代码中都是安全的.这些属性位于一些低级跟踪帮助程序中(如果您想知道它们为什么是内部的,则通过方法公开).
我宁愿不依赖于不需要的程序集(如System.Web等).我不想要求使用此代码的任何人配置任何东西.我只是想让它起作用;)虽然这可能太高了一个订单......
任何人都有任何诡计?(我看过Spring的实现)
internal static string CurrentInstance
{
get
{
return CallContext.LogicalGetData(currentInstanceSlotName) as string;
}
set
{
CallContext.LogicalSetData(currentInstanceSlotName, value);
}
}
internal static Stack<ActivityState> AmbientActivityId
{
get
{
Stack<ActivityState> stack = CallContext.LogicalGetData(ambientActivityStateSlotName) as Stack<ActivityState>;
if (stack == null)
{
stack = new Stack<ActivityState>();
CallContext.LogicalSetData(ambientActivityStateSlotName, stack);
}
return stack;
}
}
Run Code Online (Sandbox Code Playgroud)
更新
安全我不是说同步.背景在这个问题上这里