Spring作用域與線程安全

Spring的作用域

  • singleton(單例):默認(rèn)的scope,每個scope屬性來表示該bean的作用域,是bean的聲明周期。作用域為單例表示bean在第一次被注入時會創(chuàng)建一個單例對象,改對象會一直被復(fù)用到應(yīng)用結(jié)束
  • prototype(多例):bean被定義為在每次注入時都會創(chuàng)建一個新的對象
  • request:bean被定義為在每個http請求中創(chuàng)建一個單例對象,也就是說在單個請求中都會復(fù)用這一個單例對象
  • session:bean被定義為在一個session的生命周期內(nèi)創(chuàng)建一個單例對象
  • application:bean被定義為在servletContext的生命周期中復(fù)用一個單例對象
  • websocket:bean被定義為在websocket的生命周期中復(fù)用一個單例對象

無狀態(tài)對象

  • 由Spring管理得大多數(shù)對象其實都是一些無狀態(tài)的對象,這些對象不會因為多線程而導(dǎo)致狀態(tài)破壞很適合Spring的默認(rèn)scope.每個單例的無狀態(tài)對象都是好線程安全的,換言之,只要是無狀態(tài)的對象,不管是單例還是多例,都是線程安全的,只不過單例節(jié)省了不斷常見對象和GC的開銷。
  • 無狀態(tài)的對象包括常用的DO,DTO,VO等只是作為數(shù)據(jù)的實體模型的對象,還有Service,DAO,Controller這些沒有自己的狀態(tài),只是用來執(zhí)行某些操作。

Bean的安全使用

Spring對于bean的多線程安全問題沒有任何保證與措施,對于每個bean的線程安全問題,根本原因在于對每個bean自身的設(shè)計,不要在bean中聲明任何有狀態(tài)的實例變量或類變量,如果必須設(shè)置,那么可以使用ThreadLocal把變量變?yōu)榫€程私有,如果bean的實例變量或類變量需要在多個線程之間共享,那么需要使用syncronized,lock,CAS等實現(xiàn)線程同步

ThreadLocal的使用

  • ThreadLocal思想就是為線程提供一個線程私有的變量副本,這個多個線程可以所以修改自己線程局部的變量,不會影響其他線程。ThreadLocal含有一個ThreadLocalMap的內(nèi)部類,該類采取線性探測法實現(xiàn)HashMap,它的key值r為ThreadLocal對象并采用軟引用的方式來存儲變量副本
  • ThreadLocal提供的是淺拷貝,如果需要解決內(nèi)部狀態(tài)被改變的問題,可以通過重寫其內(nèi)部的initialValue()方法來實現(xiàn)深拷貝
  • ThreadLocal與鎖機(jī)制不一樣的地方在于,鎖更強調(diào)的是如何同步多個線程去正確共享一個變量,ThreadLocal則是為了解決同一個變量如何不被多個線程共享。從性能開銷的角度來看,如果鎖機(jī)制是時間換空間,那threadlocal就是空間換時間
  • 為了安全使用ThreadLocal,必須像每次使用完鎖就解鎖一樣,在每次使用ThreadLocal后都要調(diào)用remove()來清理無效的Entry
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容