我在读这文章关于Java的ThreadLocal的对象,试图理解为什么以及何时会使用它们。在本文中,我遇到了一个示例,旨在演示如何使用 ThreadLocal。它是一个应该是事务管理器的类,它使用了一个在整个类中使用的静态事务 ID 变量。为了使类线程安全,它使用 ThreadLocal 作为 transactionID:
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 变量。
在某些情况下,差异会发生变化,但让我们尝试一些事情:
我将假设示例的大纲类似于“我们正在某个流程中执行多个步骤,我们想要生成一个事务 ID 来标识该流程的一次执行。对于任何给定的执行,所有这些步骤都在同一线程中运行”
在这种情况下,不同之处在于,如果您将其设为实例变量(是的,您可以做到),您将必须创建您的 transactionId 并在您可能需要将其作为参数的所有层和类中传播 TransactionManager 实例,使您的方法签名比需要的更脏(假设您有一个 StepExecution 接口并且所有步骤都实现了该接口,但并非所有步骤都可能需要访问 transactionID,然后您将在方法签名中混入一个无用的参数)
不仅如此,ThreadLocal 将保证您正在访问的值是您在同一线程上生成的值,从而防止线程之间的信息“泄漏”,使其完全线程安全。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句