Spring如何保證線程安全

Spring 的常見業務組件採取單例如何保證線程安全

Spring 作爲 IOC 框架,一般來說,Spring 管理的 controller、service、dao 都是單例存在,節省內存和 cpu、提高單機資源利用率(默認單例,配置多例模式使用 scope=prototype),既然是單例,那麼如何控制單例被多個線程同時訪問線程安全呢?

首先要理解每個 http 請求到後臺都是一個單獨的線程,線程之間共享同一個進程的內存、io、cpu 等資源,但線程棧是線程獨有,線程之間不共享棧資源

其次,bean 分爲有狀態 bean 和無狀態 bean,有狀態 bean 即類定義了成員變量,可能被多個線程同時訪問,則會出現線程安全問題;無狀態 bean 每個線程訪問不會產生線程安全問題,因爲各個線程棧及方法棧資源都是獨立的,不共享。即是,無狀態 bean 可以在多線程環境下共享,有狀態 bean 不能

Spring 的 dao、service 層使用的有狀態 bean 如何保證線程安全

Spring 應用中 dao、service 一般以單例形式存在,dao、service 中使用的數據庫 connection 以及 RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder 等都是有狀態 bean,而 dao、service 又是單例,如何保證線程安全呢?

答案是使用 threadLocal 進行處理,ThreadLocal 是線程本地變量,每個線程擁有變量的一個獨立副本,所以各個線程之間互不影響,保證了線程安全

SpringMVC 的 controller 併發訪問

SpringMVC 中的 controller 默認是單例的,那麼如果不小心在類中定義了類變量,那麼這個類變量是被所有請求共享的,這可能會造成多個請求修改該變量的值,出現與預期結果不符合的異常。所以如上所述,屬性變量會到值線程安全問題,解決方法包括使用 threadLocal 或不使用屬性變量、配置爲多例均可(加鎖控制效率不行)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章