这是我偶然发现的代码:
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,它是类中唯一的字段.
在我看来,这里不需要同步,因为存储在ThreadLocal中的值与特定线程相关联,因此它不是共享状态.此外,我认为它会影响性能,因为currentTransactionContext本身是共享的,只允许一个线程进入块,而许多线程可以并行执行而不影响正确性.
这里需要同步吗?
解决方法
一般来说,由于线程安全性是整个程序的一个属性,因此很难仅仅通过一小部分程序来保证线程安全性,并且synchronized可以协调程序的许多不同部分的行为.
例如:也许在其他地方有一些其他的代码片段使用疯狂的不安全反射来尝试检查和/或改变ThreadLocal的内容,如果你在没有锁定的情况下改变ThreadLocal,那么这将会中断?
但实际上,你是对的:除了可能在其initialValue方法中之外,从来没有任何理由在ThreadLocal实例上进行同步. ThreadLocal本身就是一个线程安全机制,它可以更好地管理其线程安全性.
(用于指出initialValue案例的Hat-tip到Margaret Bloom.)