gpt4 book ai didi

java - 在这种高流量的多线程场景中,我应该使用 ThreadLocal 吗?

转载 作者:行者123 更新时间:2023-11-30 10:34:00 25 4
gpt4 key购买 nike

场景

我们正在开发一种 API,可以在多线程环境中每小时处理大约 2-3 百万次点击。服务器是 Apache Tomcat 7.0.64。

我们有一个包含大量数据的自定义对象,我们称它为 XYZDataContext。当收到新请求时,我们将 XYZDataContext 对象关联到请求上下文。每个请求一个 XYZDataContext 对象。我们将并行生成各种线程来满足从 XYZDataContext 对象收集数据/处理数据到 XYZDataContext 对象的请求。我们将并行处理事物的线程需要访问此 XYZDataContext 对象,并且为了避免在应用程序的任何地方将此对象传递给各种对象/方法/线程,我们正在考虑使它成为线程本地的。线程将使用来自 XYZDataContext 对象的数据,并将更新该对象中的数据。当线程结束时,我们计划将生成的子线程中更新的 XYZDataContext 对象中的数据合并到主线程的 XYZDataContext 对象中。

我的问题:

  1. 这是一个好方法吗?

  2. 线程池风险 - Tomcat 服务器将维护一个线程池,我读到将 threadlocal 与线程池一起使用是一场灾难,因为线程不是按说进行 GC 处理而是被重用,因此对 threadlocal 对象的引用不会进行 GC 处理,并且会导致在内存中存储我们不再需要的巨大对象,最终导致 OutOfMemory 问题...

    除非它们被引用为弱引用,以便立即进行 GC。
    我们使用的是 Java 1.7 开放的 JDK。我看到了 ThreadLocal 的源代码,虽然 ThreadLocalMap.Entry 是一个弱引用,但它没有与 ReferenceQueue 相关联,并且 Entry 构造函数的注释说“由于未使用引用队列,陈旧只有当表开始空间不足时,才能保证删除条目。"

    我想这在缓存的情况下效果很好,但在我们的情况下并不是最好的。我希望立即对线程本地 XYZDataContext 对象进行 GC。 ThreadLocal.remove()方法在这里会生效吗?有没有什么办法可以在下一次 GC 运行时强制清空空间?

  3. 这是使用 ThreadLocal 对象的正确方案吗?或者我们是否在滥用线程局部概念并在不应该使用它的地方使用它?

最佳答案

我的直觉告诉我你走错了路。由于您已经有一个中央上下文对象(一个用于所有线程)并且您希望同时从多个线程访问它,我会选择一个托管上下文对象并提供线程安全方法来访问它的单例。

我强烈建议同时进行所有操作,而不是操作上下文对象的多个属性。最好的情况是您只传递一个对象,其中包含您要在上下文对象中更改的所有属性。

例如

Singleton.getInstance().adjustContext(ContextAdjuster contextAdjuster)

您可能还想考虑使用线程安全队列,用线程中的 ContextAdjuster 对象填充它,最后在 Context 的线程中处理它。

谷歌搜索 Java 中的并发、阻塞和非阻塞队列。我相信您会找到大量示例代码。

关于java - 在这种高流量的多线程场景中,我应该使用 ThreadLocal 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41918081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com