提到ThreadLocal被提到應(yīng)用最多的是session管理和數(shù)據(jù)庫鏈接管理,這里以數(shù)據(jù)訪問為例幫助你理解ThreadLocal:
如下數(shù)據(jù)庫管理類在單線程使用是沒有任何問題的
很顯然,在多線程中使用會存在線程安全問題:,這里面的2個方法都沒有進(jìn)行同步,很可能在openConnection方法中會多次創(chuàng)建connect;第二,由于connect是共享變量,那么必然在調(diào)用connect的地方需要使用到同步來保障線程安全,因為很可能一個線程在使用connect進(jìn)行數(shù)據(jù)庫操作,而另外一個線程調(diào)用closeConnection關(guān)閉鏈接。
為了解決上述線程安全的問題,考慮:互斥同步
你可能會說,將這段代碼的兩個方法進(jìn)行同步處理,并且在調(diào)用connect的地方需要進(jìn)行同步處理,比如用Synchronized或者ReentrantLock互斥鎖。
這里再拋出一個問題:這地方到底需不需要將connect變量進(jìn)行共享?
事實上,是不需要的。假如每個線程中都有一個connect變量,各個線程之間對connect變量的訪問實際上是沒有依賴關(guān)系的,即一個線程不需要關(guān)心其他線程是否對這個connect進(jìn)行了修改的。
即改后的代碼可以這樣:
這樣處理確實也沒有任何問題,由于每次都是在方法內(nèi)部創(chuàng)建的連接,那么線程之間自然不存在線程安全問題。但是這樣會有一個致命的影響:導(dǎo)致服務(wù)器壓力非常大,并且嚴(yán)重影響程序執(zhí)行性能。由于在方法中需要頻繁地開啟和關(guān)閉數(shù)據(jù)庫連接,這樣不僅嚴(yán)重影響程序執(zhí)行效率,還可能導(dǎo)致服務(wù)器壓力巨大。
這時候ThreadLocal登場了
那么這種情況下使用ThreadLocal是再適合不過的了,因為ThreadLocal在每個線程中對該變量會創(chuàng)建一個副本,即每個線程內(nèi)部都會有一個該變量,且在線程內(nèi)部任何地方都可以使用,線程之間互不影響,這樣一來就不存在線程安全問題,也不會嚴(yán)重影響程序執(zhí)行性能。
下面就是網(wǎng)上出現(xiàn)最多的例子: