Spring 使用 ThreadLocal 解決執行緒安全問題我們知道在一般情況下,只有無狀態的Bean才可以在多執行緒環境下共享,在Spring中,絕大部分 Bean 都可以宣告為 singleton 作用域。就是因為 Spring 對一些Bean(RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder 等)中非執行緒安全狀態採用 ThreadLocal 進行處理,讓它們也成為執行緒安全的狀態,因為有狀態的Bean 就可以在多執行緒中共享了。
ThreadLocal 和執行緒同步機制都是為了解決多執行緒中相同變數訪問衝突問題。同步機制中,透過物件的鎖機制保證同一時間只有一個執行緒訪問變數。這時該變數是多個執行緒共享的,使用同步機制要求程式慎密地分析什麼時候對變數進行讀寫,什麼時候需要鎖定某個物件,什麼時候釋放物件鎖等繁雜的問題,程式設計和編寫難度相對較大。
ThreadLocal 則從另一個角度來解決多執行緒的併發訪問。ThreadLocal會為每一個執行緒提供一個獨立的變數副本,從而隔離了多個執行緒對資料的訪問衝突。因為每一個執行緒都擁有自己的變數副本,從而也就沒有必要對該變數進行同步了。ThreadLocal提供了執行緒安全的共享物件,在編寫多執行緒程式碼時,可以把不安全的變數封裝進 ThreadLocal。 由於 ThreadLocal中可以持有任何型別的物件,低版本 JDK 所提供的 get()返回的是 Object 物件,需要強制型別轉換。但 JDK5.0透過泛型很好的解決了這個問題,在一定程度地簡化ThreadLocal 的使用。
概括起來說,對於多執行緒資源共享的問題,同步機制採用了“以時間換空間”的方式,而 ThreadLocal 採用了“以空間換時間”的方式。前者僅提供一份變數,讓不同的執行緒排隊訪問,而後者為每一個執行緒都提供了一份變數,因此可以同時訪問而互不影響。
Spring 使用 ThreadLocal 解決執行緒安全問題我們知道在一般情況下,只有無狀態的Bean才可以在多執行緒環境下共享,在Spring中,絕大部分 Bean 都可以宣告為 singleton 作用域。就是因為 Spring 對一些Bean(RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder 等)中非執行緒安全狀態採用 ThreadLocal 進行處理,讓它們也成為執行緒安全的狀態,因為有狀態的Bean 就可以在多執行緒中共享了。
ThreadLocal 和執行緒同步機制都是為了解決多執行緒中相同變數訪問衝突問題。同步機制中,透過物件的鎖機制保證同一時間只有一個執行緒訪問變數。這時該變數是多個執行緒共享的,使用同步機制要求程式慎密地分析什麼時候對變數進行讀寫,什麼時候需要鎖定某個物件,什麼時候釋放物件鎖等繁雜的問題,程式設計和編寫難度相對較大。
ThreadLocal 則從另一個角度來解決多執行緒的併發訪問。ThreadLocal會為每一個執行緒提供一個獨立的變數副本,從而隔離了多個執行緒對資料的訪問衝突。因為每一個執行緒都擁有自己的變數副本,從而也就沒有必要對該變數進行同步了。ThreadLocal提供了執行緒安全的共享物件,在編寫多執行緒程式碼時,可以把不安全的變數封裝進 ThreadLocal。 由於 ThreadLocal中可以持有任何型別的物件,低版本 JDK 所提供的 get()返回的是 Object 物件,需要強制型別轉換。但 JDK5.0透過泛型很好的解決了這個問題,在一定程度地簡化ThreadLocal 的使用。
概括起來說,對於多執行緒資源共享的問題,同步機制採用了“以時間換空間”的方式,而 ThreadLocal 採用了“以空間換時間”的方式。前者僅提供一份變數,讓不同的執行緒排隊訪問,而後者為每一個執行緒都提供了一份變數,因此可以同時訪問而互不影響。