问题标签 [thread-local]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
3242 浏览

java - ThreadLocal + java.sql.Connection + servlet 过滤器 = 2009?

我正在编写一些带有普通旧的主要是 JDBC 模式的 servlet。我意识到我有几个对象想要共享一个事务,并且我想强制执行一个 HTTP 事务 = 一个数据库事务。

我想我可以通过在 ThreadLocal 变量中传递一个 Connection 来做到这一点,然后让一个 servlet 过滤器处理所述 Connection 的创建/提交/回滚。

是否有一个我不知道的现有框架可以做到这一点,或者这是一种合理的 00 后做事方式?

0 投票
4 回答
2075 浏览

python - 如何在 Python 中将变量放在堆栈/上下文中

本质上,我想在堆栈上放置一个变量,堆栈上该部分下方的所有调用都可以访问该变量,直到块退出。在Java中,我会使用支持方法的本地静态线程来解决这个问题,然后可以从方法中访问它。

典型例子:你得到一个请求,并打开一个数据库连接。在请求完成之前,您希望所有代码都使用此数据库连接。完成并关闭请求后,关闭数据库连接。

我需要这个,是一个报告生成器。每个报告由多个部分组成,每个部分可以依赖于不同的计算,有时不同的部分部分依赖于相同的计算。因为我不想重复繁重的计算,所以我需要缓存它们。我的想法是用缓存装饰器来装饰方法。缓存根据方法名称和模块创建一个 id,它是参数,查看它是否已经在堆栈变量中计算了这个,如果没有,则执行该方法。

我将通过展示我当前的实现来尝试和清除。我想做的是简化那些实现计算的代码。

首先,我有中央缓存访问对象,我称之为 MathContext:

fn 参数是创建上下文相关的文件名,可以从中读取数据以进行计算。

然后我们有 Calculation 类:

这是一个愚蠢的斐波那契示例。这些方法实际上都不是递归的,它们适用于大量数据,但它可以证明您将如何依赖其他计算:

相反,我希望斐波那契只是一种装饰方法:

在 math_context 示例中,当 math_context 超出范围时,它的所有缓存值也会如此。我想要装饰师也一样。IE。在 X 点,@cache 缓存的所有内容都被取消引用为 gced。

0 投票
4 回答
3370 浏览

java - 如何覆盖 ObjectOutputStream.writeStreamHeader()?

ObjectOutputStream.writeStreamHeader()可以重写该方法以将数据附加或附加到标头。但是,如果该数据基于传递给派生类构造函数的参数,例如:

它不起作用,因为在被初始化super()之前被调用并调用. 我能想到解决这个问题的唯一方法是使用类似:m_myDatasuper()writeStreamHeader()ThreadLocal

这似乎可行,但是有更好(不那么笨重)的方法吗?

0 投票
5 回答
15237 浏览

java - Java 的 ThreadLocal 是如何在底层实现的?

ThreadLocal 是如何实现的?它是用 Java 实现的(使用一些从 ThreadID 到对象的并发映射),还是使用一些 JVM 挂钩来更有效地完成它?

0 投票
6 回答
7728 浏览

c++ - 在哪些平台上线程本地存储受到限制,可用的空间有多少?

我最近意识到线程本地存储在某些平台上是有限的。例如,C++ 库 boost::thread 的文档如下:

“注意:可以创建的线程特定存储对象的数量有一个特定于实现的限制,这个限制可能很小。”

我一直在寻找尝试找出不同平台的限制,但我一直无法找到权威的表格。如果您正在编写使用 TLS 的跨平台应用程序,这是一个重要的问题。Linux 是我找到信息的唯一平台,其形式是 Ingo Monar 在 2002 年向内核列表发送了一个补丁,添加了 TLS 支持,他在其中提到,“TLS 区域的数量是无限的,并且没有相关的额外分配开销支持 TLS。” 如果在 2009 年仍然如此(是吗?),那真是太棒了。

但是今天的 Linux 呢?操作系统?视窗?索拉里斯?嵌入式操作系统?对于在多种架构上运行的操作系统,它是否因架构而异?

编辑:如果您好奇为什么可能会有限制,请考虑线程本地存储的空间将被预先分配,因此您将在每个线程上为此付出成本。面对大量线程,即使是少量也可能是个问题。

0 投票
6 回答
21757 浏览

java - ThreadLocal 的目的?

此处给出的 ThreadLocal 的目的表明该变量对于任何访问包含 ThreadLocal 变量的对象的线程都是本地的。它有什么区别,将 ThreadLocal 变量作为类的成员,然后使其成为 Thread 的本地变量,而不是 Thread 本身的局部变量?

0 投票
3 回答
2356 浏览

java - 线程本地实现

参考我之前的问题,更进一步,

  1. 与局部变量相比,使用 ThreadLocals 的缺点是什么
  2. 它们是如何实施的
  3. 会话变量是 ThreadLocals
  4. 是否有更多常用的ThreadLocals的例子
0 投票
4 回答
4470 浏览

java - 变量的同步和本地副本

我正在查看一些具有以下习语的遗留代码:

我从 Intelli-J 的代码检查中得到的警告是:

这是适当的同步吗?为什么?

0 投票
1 回答
777 浏览

java - Java 实例变量可见性 (ThreadLocal)

在类ReentrantReadWriteLock中有以下奇怪的评论:

“确保可见性”是什么意思?我问的原因是我有一种情况,看起来好像线程本地 readHolds 正在被重置(线程本地被实现为 WeakReferences,因此只要包含的 Sync 对象仍然存在,就不应该发生这种情况)。setState/getState 只是简单地改变另一个实例变量并且不触及 readHolds。

0 投票
9 回答
9802 浏览

java - 如何强制 Java 线程关闭线程本地数据库连接

使用线程本地数据库连接时,需要在线程存在时关闭连接。

只有当我可以覆盖调用线程的 run() 方法时,我才能做到这一点。即使这也不是一个很好的解决方案,因为在退出时,我不知道该线程是否曾经打开过连接。

这个问题实际上更普遍:如何强制线程在退出时调用线程本地对象的某些终结方法。

我查看了java 1.5的源码,发现线程本地映射设置为null,最终会导致垃圾收集调用finalize(),但我不想指望垃圾收集器。

为了确保关闭数据库连接,以下覆盖似乎是不可避免的:

其中release()关闭数据库连接,如果它已打开。但是我们不知道线程是否曾经使用过这个线程本地。如果 get() 从来没有被这个线程调用过,那么这里就很浪费精力:将调用ThreadLocal.initialValue(),将在这个线程上创建一个映射,等等。


根据 Thorbjørn 的评论,进一步澄清和举例:

java.lang.ThreadLocal是一种绑定到线程的对象的工厂类型。这种类型有一个对象的 getter 和一个工厂方法(通常由用户编写)。当 getter 被调用时,它仅在该线程之前从未调用过它时才调用工厂方法。

使用ThreadLocal允许开发人员将资源绑定到线程,即使线程代码是由第三方编写的。

示例:假设我们有一个名为MyType的资源类型,我们希望每个线程只有一个资源类型。

在使用类中定义:

在此类的本地上下文中使用:

get()在调用线程的生命周期中只能调用一次initialValue() 。此时,MyType的一个实例被实例化并绑定到该线程。此线程对get()的后续调用再次引用此对象。

经典用法示例是MyType是一些线程不安全的文本/日期/xml 格式化程序。

但是这样的格式化程序通常不需要释放或关闭,数据库连接需要,我使用java.lang.ThreadLocal来为每个线程建立一个数据库连接。

在我看来,java.lang.ThreadLocal几乎是完美的。几乎是因为如果调用线程属于第三方应用程序,则无法保证资源的关闭。

我需要你的聪明才智:通过扩展java.lang.ThreadLocal,我设法为每个线程绑定了一个数据库连接,因为它是专用的——包括我无法修改或覆盖的线程。我设法确保连接关闭,以防线程因未捕获的异常而死亡。

在正常线程退出的情况下,垃圾收集器关闭连接(因为MyType覆盖了finalize())。实际上它发生得很快,但这并不理想。

如果我按照自己的方式行事,那么java.lang.ThreadLocal上会有另一种方法:

如果此方法存在于java.lang.ThreadLocal上,由 JVM 在任何线程退出/死亡时调用,那么在我自己的覆盖中我可以关闭我的连接(并且救赎者会来到锡安)。

在没有这种方法的情况下,我正在寻找另一种方法来确认关闭。一种不依赖 JVM 垃圾收集的方法。