ThreadLocal上的操作是否必须同步?

时间:2016-12-25 18:40:50

标签: java multithreading performance synchronized thread-local

以下是我偶然发现的代码:

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本身是共享的,只允许一个线程进入块,而许多线程可以并行执行而不影响正确性。

这里需要同步吗?

1 个答案:

答案 0 :(得分:6)

一般来说,由于线程安全是整个程序的一个属性,因此很难仅仅通过程序的一小部分就做出关于线程安全的保证,并且synchronized可以协调许多程序的行为程序的不同部分。

例如:也许在其他地方有一些其他代码使用疯狂的不安全反射来尝试检查和/或改变ThreadLocal的内容,如果你在没有锁定的情况下改变ThreadLocal,那么这会破坏?

但实际上,你是对的:除了可能在initialValue方法内部之外,从来没有任何理由在ThreadLocal实例上进行同步。 ThreadLocal本身就是一个线程安全机制,它可以比你在synchronized上更好地管理它的线程安全性。

(提示initialValue指出var row, cell, text, r, c, prop = ['id', 'data', 'mama'], table = document.getElementById("myList1"); for (r = 0; r < data.length; r++) { row = document.createElement('tr'); for (c = 0; c < 3; c++) { cell = document.createElement('td'); text = document.createTextNode(data[r][prop[c]]); cell.appendChild(text); row.appendChild(cell); } table.appendChild(row); } 案例。(