当前位置: 首页 > 面试题库 >

实例级线程本地存储的优点是什么?

郎弘业
2023-03-14
问题内容

这个问题使我想知道Java和.NET等高级开发框架中的线程本地存储。

Java有一个ThreadLocal<T>类(也许还有其他结构),而.NET有数据插槽,很快就有ThreadLocal<T>了自己的类。(它也具有ThreadStaticAttribute,但我对成员数据的线程本地存储特别感兴趣。)大多数其他现代开发环境都在语言或框架级别为其提供了一种或多种机制。

线程本地存储解决了哪些问题,或者与创建独立对象实例以包含线程本地数据的标准的面向对象的习语相比,线程本地存储提供了哪些优势?换句话说,这是怎么回事:

// Thread local storage approach - start 200 threads using the same object
// Each thread creates a copy of any thread-local data
ThreadLocalInstance instance = new ThreadLocalInstance();
for(int i=0; i < 200; i++) {
    ThreadStart threadStart = new ThreadStart(instance.DoSomething);
    new Thread(threadStart).Start();
}

优越于此?

// Normal oo approach, create 200 objects, start a new thread on each
for(int i=0; i < 200; i++) {
    StandardInstance standardInstance = new StandardInstance();
    ThreadStart threadStart = new ThreadStart(standardInstance.DoSomething);      
    new Thread(threadStart).Start();
}

我可以看到,将单个对象与线程本地存储一起使用会稍微提高内存效率,并且由于分配(和构造)较少而需要更少的处理器资源。还有其他优势吗?


问题答案:

线程本地存储解决了哪些问题,或者与创建独立对象实例以包含线程本地数据的标准的面向对象的习语相比,线程本地存储提供了哪些优势?

线程本地存储允许您为每个正在运行的线程提供一个类的唯一实例,这在尝试使用非线程安全类或避免由于共享状态而可能发生的同步要求时非常有用。

至于与示例相比的优势-如果生成单个线程,则与传递实例相比,使用线程本地存储几乎没有优势。
ThreadLocal<T>但是,当(直接或间接)使用ThreadPool时,类似的构造变得非常有价值。

例如,我最近有一个特定的工作过程,在该过程中,我们使用.NET中的新任务并行库进行大量的计算。可以对执行的计算的某些部分进行缓存,如果缓存中包含特定的匹配项,则在处理一个元素时可以节省大量时间。但是,缓存的信息对内存的要求很高,因此我们不希望缓存的内容超过最后一个处理步骤。

但是,尝试在线程之间共享此缓存是有问题的。为了做到这一点,我们必须同步对它的访问,并在类内部添加一些额外的检查以使它们线程安全。

而不是这样做,我重写了算法,以允许每个线程在中维护自己的私有缓存ThreadLocal<T>。这允许线程各自维护自己的私有缓存。由于TPL使用的分区方案倾向于将元素块保持在一起,因此每个线程的本地缓存倾向于包含其所需的适当值。

这消除了同步问题,但也使我们能够将缓存保持在原位。在这种情况下,整体收益非常大。

作为一个更具体的示例,请看一下我使用TPL编写的有关聚合的博客文章。在内部,ThreadLocal<TLocal>每当您使用ForEach重载时,Parallel类都会使用a
来保持局部状态(以及Parallel.For<TLocal>方法)。这是将本地状态与每个线程分开的方式,以避免锁定。



 类似资料:
  • 问题内容: 实际上如何解决“ foo”?编译器是否以函数调用静默替换“ foo”的每个实例?“ foo”是否存储在相对于堆栈底部的某个位置,并且编译器将其存储为“嘿,对于每个线程,此空间都位于堆栈底部附近,而foo存储为’距堆栈底部的偏移量x”。 “? 问题答案: 这有点复杂(本文档对此进行了详细说明),但实际上两者都不是。而是,编译器在可执行文件中放置一个特殊的.tdata节,其中包含所有线程局

  • 线程本地存储指针允许开发者存储值到任务的控制块(control block)中,使这个值对于任务来说是特定且唯一的。 线程本地存储经常被用来存储数据,而单一进程的应用程序通常的做法是使用全局变量。比如,很多库函数包含一个全局的返回值--错误信息,应用根据这个错误信息判读错误类型,同时进行相应处理。在单线程的应用中可以使用全局变量来保存这个错误信息,但是在多任务的系统中,每个任务都必须有一个自己的位

  • 问题内容: 特别是在Python中,如何在线程之间共享变量? 尽管我以前从未使用过,但从未真正理解或看到过如何共享变量的示例。它们是在主线程和子线程之间共享还是仅在子线程之间共享?我何时需要使用线程本地存储来避免这种共享? 我已经看到许多有关通过使用锁在线程之间同步对共享数据的访问的警告,但是我还没有看到这个问题的一个很好的例子。 提前致谢! 问题答案: 在Python中,所有内容都是共享的,但函

  • 问题内容: 如何在Python中使用线程本地存储? 有关 Python中的“线程本地存储”是什么,为什么需要它?-共享变量时,该线程似乎更加关注。 问题答案: 例如,如果您有一个线程工作池,并且每个线程都需要访问其自己的资源(例如网络或数据库连接),则线程本地存储很有用。请注意,该模块使用常规的线程概念(可以访问进程全局数据),但是由于全局解释器锁定,它们并不是太有用。不同的模块会为每个模块创建一

  • 抱歉,目前我还没有完成这个主题,请稍后再来。 如果你对这一主题感兴趣,可以参考本站的: C++小品:井水不犯河水的thread_specific_ptr,C++11线程库中的本地存储 C++小品:井水不犯河水在PPL中的实现:combinable以及task_group,task 参考: [N2659 = 08-0169] Lawrence Crowl: Thread-Local Storage

  • 本文向大家介绍Html5中本地存储概念是什么,有什么优点,与cookie有什么区别?相关面试题,主要包含被问及Html5中本地存储概念是什么,有什么优点,与cookie有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。 sessionStorage用于本地存储一个会话(sessio