ThreadLocal 上的操作是否必须同步?
Do operations on ThreadLocal have to be synchronized?
这是我偶然发现的代码:
class TransactionContextHolder {
private static final ThreadLocal<TransactionContext> currentTransactionContext = new NamedInheritableThreadLocal<TransactionContext>(
"Test Transaction Context");
static TransactionContext getCurrentTransactionContext() {
return currentTransactionContext.get();
}
static void setCurrentTransactionContext(TransactionContext transactionContext) {
currentTransactionContext.set(transactionContext);
}
static TransactionContext removeCurrentTransactionContext() {
synchronized (currentTransactionContext) {
TransactionContext transactionContext = currentTransactionContext.get();
currentTransactionContext.remove();
return transactionContext;
}
}
}
currentTransactionContext 字段是 ThreadLocal 类型,它是 class 中唯一的字段。
在我看来,这里不需要同步,因为存储在 ThreadLocal 中的值与特定线程关联,因此它不是共享状态。此外,我认为它会影响性能,因为 currentTransactionContext 本身是共享的,并且只允许一个线程进入块,而许多线程可以并行执行而不影响正确性。
这里需要同步吗?
一般来说,很难保证线程安全,因为线程安全是整个程序的属性,并且synchronized
可以协调程序中许多不同部分的行为。
例如:也许在其他地方有一些其他代码使用疯狂的不安全反射来尝试检查 and/or 改变 ThreadLocal 的内部结构,因此如果你在没有锁定的情况下改变 ThreadLocal 就会中断?
但实际上,您是完全正确的:没有任何理由在 ThreadLocal 实例上进行同步,也许在其 initialValue
方法内部除外。 ThreadLocal 本身就是一种线程安全机制,它管理线程安全的能力比你通过 synchronized
获得的更好。
(向 Margaret Bloom 致敬,指出 initialValue
案例。)
这是我偶然发现的代码:
class TransactionContextHolder {
private static final ThreadLocal<TransactionContext> currentTransactionContext = new NamedInheritableThreadLocal<TransactionContext>(
"Test Transaction Context");
static TransactionContext getCurrentTransactionContext() {
return currentTransactionContext.get();
}
static void setCurrentTransactionContext(TransactionContext transactionContext) {
currentTransactionContext.set(transactionContext);
}
static TransactionContext removeCurrentTransactionContext() {
synchronized (currentTransactionContext) {
TransactionContext transactionContext = currentTransactionContext.get();
currentTransactionContext.remove();
return transactionContext;
}
}
}
currentTransactionContext 字段是 ThreadLocal 类型,它是 class 中唯一的字段。
在我看来,这里不需要同步,因为存储在 ThreadLocal 中的值与特定线程关联,因此它不是共享状态。此外,我认为它会影响性能,因为 currentTransactionContext 本身是共享的,并且只允许一个线程进入块,而许多线程可以并行执行而不影响正确性。
这里需要同步吗?
一般来说,很难保证线程安全,因为线程安全是整个程序的属性,并且synchronized
可以协调程序中许多不同部分的行为。
例如:也许在其他地方有一些其他代码使用疯狂的不安全反射来尝试检查 and/or 改变 ThreadLocal 的内部结构,因此如果你在没有锁定的情况下改变 ThreadLocal 就会中断?
但实际上,您是完全正确的:没有任何理由在 ThreadLocal 实例上进行同步,也许在其 initialValue
方法内部除外。 ThreadLocal 本身就是一种线程安全机制,它管理线程安全的能力比你通过 synchronized
获得的更好。
(向 Margaret Bloom 致敬,指出 initialValue
案例。)