javascript
controller如何保证当前只有一个线程执行_聊聊Spring线程安全,读完之后,大部分程序员收藏了......
Spring作為一個IOC/DI容器,幫助我們管理了許許多多的“bean”。但其實,Spring并沒有保證這些對象的線程安全,需要由開發者自己編寫解決線程安全問題的代碼。
Spring對每個bean提供了一個scope屬性來表示該bean的作用域。它是bean的生命周期。例如,一個scope為singleton的bean,在第一次被注入時,會創建為一個單例對象,該對象會一直被復用到應用結束。
- singleton:默認的scope,每個scope為singleton的bean都會被定義為一個單例對象,該對象的生命周期是與Spring IOC容器一致的(但在第一次被注入時才會創建)。
- prototype:bean被定義為在每次注入時都會創建一個新的對象。
- request:bean被定義為在每個HTTP請求中創建一個單例對象,也就是說在單個請求中都會復用這一個單例對象。
- session:bean被定義為在一個session的生命周期內創建一個單例對象。
- application:bean被定義為在ServletContext的生命周期中復用一個單例對象。
- websocket:bean被定義為在websocket的生命周期中復用一個單例對象。
我們交由Spring管理的大多數對象其實都是一些無狀態的對象,這種不會因為多線程而導致狀態被破壞的對象很適合Spring的默認scope,每個單例的無狀態對象都是線程安全的(也可以說只要是無狀態的對象,不管單例多例都是線程安全的,不過單例畢竟節省了不斷創建對象與GC的開銷)。
無狀態的對象即是自身沒有狀態的對象,自然也就不會因為多個線程的交替調度而破壞自身狀態導致線程安全問題。無狀態對象包括我們經常使用的DO、DTO、VO這些只作為數據的實體模型的貧血對象,還有Service、DAO和Controller,這些對象并沒有自己的狀態,它們只是用來執行某些操作的。例如,每個DAO提供的函數都只是對數據庫的CRUD,而且每個數據庫Connection都作為函數的局部變量(局部變量是在用戶棧中的,而且用戶棧本身就是線程私有的內存區域,所以不存在線程安全問題),用完即關(或交還給連接池)。
有人可能會認為,我使用request作用域不就可以避免每個請求之間的安全問題了嗎?這是完全錯誤的,因為Controller默認是單例的,一個HTTP請求是會被多個線程執行的,這就又回到了線程的安全問題。當然,你也可以把Controller的scope改成prototype,實際上Struts2就是這么做的,但有一點要注意,Spring MVC對請求的攔截粒度是基于每個方法的,而Struts2是基于每個類的,所以把Controller設為多例將會頻繁的創建與回收對象,嚴重影響到了性能。
關注
感謝閱讀,如果這篇文章幫助了您,歡迎 點贊 ,收藏,關注,轉發 喲。您的幫助是我們前行的動力,我們會提供更多有價值的內容給大家... 謝謝!
總結
以上是生活随笔為你收集整理的controller如何保证当前只有一个线程执行_聊聊Spring线程安全,读完之后,大部分程序员收藏了......的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工程打包是什么意思_太生动形象了!500
- 下一篇: 响应式网站怎么设置(响应式网站怎么设置密