Java 为什么不使用实例对象而不是 ThreadLocal?
Why Not Use Instance Objects Instead of ThreadLocal in Java?
我正在阅读 this Java 中关于 ThreadLocal 对象的文章,试图了解为什么以及何时使用它们。在这篇文章中,我遇到了一个示例,旨在演示如何使用 ThreadLocal。它是一个本应作为事务管理器的 class,它使用了一个在整个 class 中使用的静态 transactionID 变量。为了使 class 线程安全,它为 transactionID 使用了 ThreadLocal:
public class TransactionManager {
private static final ThreadLocal<String> context = new
ThreadLocal<String();
public static void startTransaction() {
//logic to start a transaction
//...
context.set(generatedId);
}
public static String getTransactionId() {
return context.get();
}
public static void endTransaction() {
//logic to end a transaction
//…
context.remove();
}
}
我的问题是,为什么不直接将 transactionID 设为实例变量,而不是首先将其设为静态?这样你就不需要使用 ThreadLocal 变量。
在某些情况下差异会发生变化,但让我们尝试一些事情:
我假设示例的概要类似于 "We are executing several steps in some process and we want to generate a transactionID to identify one execution of the process. All those steps run in the same thread for any given execution"
在这种情况下,不同之处在于,如果您将其设为实例变量(是的,您可以这样做),您将必须创建您的 transactionId 并将 TransactionManager 实例传播到所有层和 类 你可能需要它作为参数,使你的方法签名比需要的更脏(假设你有一个 StepExecution 接口并且所有步骤都实现该接口,但并非所有步骤都可能需要访问 transactionID,那么你将有一个无用的参数混合在你的方法签名中)
不仅如此,ThreadLocal 将保证您正在访问的值是您在同一线程上生成的值,从而防止 "leaks" 线程之间的信息使其完全线程安全。
...and it used a static transactionID
variable that was used throughout the class. In order to make the class thread safe, it used a ThreadLocal
for the transactionID
简而言之,ThreadLocal
use-case:您有一些 non-thread 感知代码make thread-safe,但它使用了一个或多个静态变量。如果每个线程都有自己独立的静态变量副本是有意义的,那么你只需弹出一个 ThreadLocal
,问题就解决了!
我正在阅读 this Java 中关于 ThreadLocal 对象的文章,试图了解为什么以及何时使用它们。在这篇文章中,我遇到了一个示例,旨在演示如何使用 ThreadLocal。它是一个本应作为事务管理器的 class,它使用了一个在整个 class 中使用的静态 transactionID 变量。为了使 class 线程安全,它为 transactionID 使用了 ThreadLocal:
public class TransactionManager {
private static final ThreadLocal<String> context = new
ThreadLocal<String();
public static void startTransaction() {
//logic to start a transaction
//...
context.set(generatedId);
}
public static String getTransactionId() {
return context.get();
}
public static void endTransaction() {
//logic to end a transaction
//…
context.remove();
}
}
我的问题是,为什么不直接将 transactionID 设为实例变量,而不是首先将其设为静态?这样你就不需要使用 ThreadLocal 变量。
在某些情况下差异会发生变化,但让我们尝试一些事情:
我假设示例的概要类似于 "We are executing several steps in some process and we want to generate a transactionID to identify one execution of the process. All those steps run in the same thread for any given execution"
在这种情况下,不同之处在于,如果您将其设为实例变量(是的,您可以这样做),您将必须创建您的 transactionId 并将 TransactionManager 实例传播到所有层和 类 你可能需要它作为参数,使你的方法签名比需要的更脏(假设你有一个 StepExecution 接口并且所有步骤都实现该接口,但并非所有步骤都可能需要访问 transactionID,那么你将有一个无用的参数混合在你的方法签名中)
不仅如此,ThreadLocal 将保证您正在访问的值是您在同一线程上生成的值,从而防止 "leaks" 线程之间的信息使其完全线程安全。
...and it used a
static transactionID
variable that was used throughout the class. In order to make the class thread safe, it used aThreadLocal
for thetransactionID
简而言之,ThreadLocal
use-case:您有一些 non-thread 感知代码make thread-safe,但它使用了一个或多个静态变量。如果每个线程都有自己独立的静态变量副本是有意义的,那么你只需弹出一个 ThreadLocal
,问题就解决了!