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