日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringMVC一个Controller处理所有用户请求的并发问题

發(fā)布時間:2025/1/21 javascript 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC一个Controller处理所有用户请求的并发问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

有狀態(tài)對象(Stateful Bean),就是有實例變量的對象 ,可以保存數(shù)據(jù),是非線程安全的。一般是prototype scope。
無狀態(tài)對象(Stateless Bean),就是沒有實例變量的對象,不能保存數(shù)據(jù),是不變類,是線程安全的。一般是singleton scope。

有狀態(tài)和無狀態(tài)的對象基本概念:

有狀態(tài)對象(Stateful Bean),就是有實例變量的對象 ,可以保存數(shù)據(jù),是非線程安全的。一般是prototype scope。
無狀態(tài)對象(Stateless Bean),就是沒有實例變量的對象,不能保存數(shù)據(jù),是不變類,是線程安全的。一般是singleton scope。

如Struts2中的Action,假如內(nèi)部有實例變量User,當(dāng)調(diào)用新增用戶方法時,user是用來保存數(shù)據(jù),那么此action是有狀態(tài)對象。多個線程同時訪問此action時 會造成user變量的不一致。所以action的scope要設(shè)計成prototype,或者,User類放到threadLocal里來保持多個線程不會造成User變量的亂串(此種場景沒必要放到threadLocal內(nèi))。

而Service內(nèi)部一般只有dao實例變量 如userDao, 因為userDao是無狀態(tài)的對象(內(nèi)部無實例變量且不能保存數(shù)據(jù)),所以service也是無狀態(tài)的對象。

public class XxxAction{// 由于多線程環(huán)境下,user是引用對象,是非線程安全的 public User user;......}public class XxxService { // 雖然有billDao屬性,但billDao是沒有狀態(tài)信息的,是Stateless Bean. BillDao billDao; ......}

對于那些會以多線程運行的單例類

局部變量不會受多線程影響,
成員變量會受到多線程影響。成員變量會受到多線程影響。

**多個線程調(diào)用同一個對象的同一個方法: **

如果方法里無局部變量,那么不受任何影響;
如果方法里有局部變量,只有讀操作,不受影響;存在寫操作,考慮多線程影響值;如果方法里有局部變量,只有讀操作,不受影響;存在寫操作,考慮多線程影響值;

例如Web應(yīng)用中的Servlet,每個方法中對局部變量的操作都是在線程自己獨立的內(nèi)存區(qū)域內(nèi)完成的,所以是線程安全的。
對于成員變量的操作,可以使用ThreadLocal來保證線程安全。

springMVC中,一般Controller、service、DAO層的scope均是singleton;

每個請求都是單獨的線程,即使同時訪問同一個Controller對象,因為并沒有修改Controller對象,相當(dāng)于針對Controller對象而言,只是讀操作,沒有寫操作,不需要做同步處理。

Service層、Dao層用默認(rèn)singleton就行,雖然Service類也有dao這樣的屬性,但dao這些類都是沒有狀態(tài)信息的,也就是 相當(dāng)于不變(immutable)類,所以不影響。

Struts2中的Action因為會有User、BizEntity這樣的實例對象,是有狀態(tài)信息 的,在多線程環(huán)境下是不安全的,所以Struts2默認(rèn)的實現(xiàn)是Prototype模式。在Spring中,Struts2的Action中scope 要配成prototype作用域。

**Spring并發(fā)訪問的線程安全性問題 **

由于Spring MVC默認(rèn)是Singleton的,所以會產(chǎn)生一個潛在的安全隱患。根本核心是instance變量保持狀態(tài)的問題。這意味著每個request過來,系統(tǒng)都會用原有的instance去處理,這樣導(dǎo)致了兩個結(jié)果:
一是我們不用每次創(chuàng)建Controller,
二是減少了對象創(chuàng)建和垃圾收集的時間;
由于只有一個Controller的instance,當(dāng)多個線程同時調(diào)用它的時候,它里面的instance變量就不是線程安全的了,會發(fā)生竄數(shù)據(jù)的問題。
當(dāng)然大多數(shù)情況下,我們根本不需要考慮線程安全的問題,比如dao,service等,除非在bean中聲明了實例變量。因此,我們在使用spring mvc 的contrller時,應(yīng)避免在controller中定義實例變量。
由于Spring MVC默認(rèn)是Singleton的,所以會產(chǎn)生一個潛在的安全隱患。根本核心是instance變量保持狀態(tài)的問題。這意味著每個request過來,系統(tǒng)都會用原有的instance去處理,這樣導(dǎo)致了兩個結(jié)果:
一是我們不用每次創(chuàng)建Controller,
二是減少了對象創(chuàng)建和垃圾收集的時間;
由于只有一個Controller的instance,當(dāng)多個線程同時調(diào)用它的時候,它里面的instance變量就不是線程安全的了,會發(fā)生竄數(shù)據(jù)的問題。
當(dāng)然大多數(shù)情況下,我們根本不需要考慮線程安全的問題,比如dao,service等,除非在bean中聲明了實例變量。因此,我們在使用spring mvc 的contrller時,應(yīng)避免在controller中定義實例變量。
如:

public class Controller extends AbstractCommandController{ ......protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,Object command,BindException errors)throwsException{company =................;}protected Company company; }

在這里有聲明一個變量company,這里就存在并發(fā)線程安全的問題。
如果控制器是使用單例形式,且controller中有一個私有的變量a,所有請求到同一個controller時,使用的a變量是共用的,即若是某個請求中修改了這個變量a,則,在別的請求中能夠讀到這個修改的內(nèi)容。。

有幾種解決方法:

1、在控制器中不使用實例變量
2、將控制器的作用域從單例改為原型,即在spring配置文件Controller中聲明 scope=“prototype”,每次都創(chuàng)建新的controller
3、在Controller中使用ThreadLocal變量

這幾種做法有好有壞,第一種,需要開發(fā)人員擁有較高的編程水平與思想意識,在編碼過程中力求避免出現(xiàn)這種BUG,而第二種則是容器自動的對每個請求產(chǎn)生一個實例,由JVM進(jìn)行垃圾回收,因此做到了線程安全。
使用第一種方式的好處是實例對象只有一個,所有的請求都調(diào)用該實例對象,速度和性能上要優(yōu)于第二種,不好的地方,就是需要程序員自己去控制實例變量的狀態(tài)保持問題。第二種由于每次請求都創(chuàng)建一個實例,所以會消耗較多的內(nèi)存空間。
所以在使用spring開發(fā)web 時要注意,默認(rèn)Controller、Dao、Service都是單例的

總結(jié)

以上是生活随笔為你收集整理的SpringMVC一个Controller处理所有用户请求的并发问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。