关于java Servlet,Struts,springMVC 的线程安全问题
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
現(xiàn)在主流的java的前端框架有:struts1,struts2,springmvc 還有最根本的servlet;
前些天一個(gè)朋友問(wèn)我這方面的問(wèn)題,就研究一番:
1.關(guān)于struts1:
Struts1使用的ActionServlet是單例的,由這一個(gè)servlet處理所有.do請(qǐng)求。RequestProcessor也是單例。
RequestProcessor的processActionCreate方法:
/***?<p>Return?an?<code>Action</code>?instance?that?will?be?used?to?process*?the?current?request,?creating?a?new?one?if?necessary.</p>**?@param?request??The?servlet?request?we?are?processing*?@param?response?The?servlet?response?we?are?creating*?@param?mapping??The?mapping?we?are?using*?@return?An?<code>Action</code>?instance?that?will?be?used?to?process*?????????the?current?request.*?@throws?IOException?if?an?input/output?error?occurs*/protected?Action?processActionCreate(HttpServletRequest?request,HttpServletResponse?response,?ActionMapping?mapping)throws?IOException?{//?Acquire?the?Action?instance?we?will?be?using?(if?there?is?one)String?className?=?mapping.getType();if?(log.isDebugEnabled())?{log.debug("?Looking?for?Action?instance?for?class?"?+?className);}Action?instance;//?這個(gè)同步快保證了Action的單例synchronized?(actions)?{//?Return?any?existing?Action?instance?of?this?classinstance?=?(Action)?actions.get(className);if?(instance?!=?null)?{if?(log.isTraceEnabled())?{log.trace("??Returning?existing?Action?instance");}return?(instance);}//?Create?and?return?a?new?Action?instanceif?(log.isTraceEnabled())?{log.trace("??Creating?new?Action?instance");}try?{instance?=?(Action)?RequestUtils.applicationInstance(className);//?Maybe?we?should?propagate?this?exception//?instead?of?returning?null.}?catch?(Exception?e)?{log.error(getInternal().getMessage("actionCreate",mapping.getPath()),?e);response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,getInternal().getMessage("actionCreate",?mapping.getPath()));return?(null);}actions.put(className,?instance);if?(instance.getServlet()?==?null)?{instance.setServlet(this.servlet);}}return?(instance);}從結(jié)果可以知道,是單例,既然是單例,如果當(dāng)使用實(shí)例變量的時(shí)候就會(huì)有線程安全的問(wèn)題;
2.關(guān)于struts2
我們知道我們使用struts2的時(shí)候,都是使用actionContext ;都是使用里面的實(shí)例變量,讓struts2自動(dòng)匹配成對(duì)象的。如果不是線程安全那全完了;所以struts2必須是線程安全的;因?yàn)槊看翁幚硪粋€(gè)請(qǐng)求,struts就會(huì)實(shí)例化一個(gè)對(duì)象;這樣就不會(huì)有線程安全的問(wèn)題了;
哦,忘記了一種情況,struts2+spring來(lái)管理注入的時(shí)候;如果把a(bǔ)ction設(shè)置為單例模式,就會(huì)出現(xiàn)問(wèn)題;可以把a(bǔ)ction設(shè)置為prototype類型,還有一個(gè)辦法是設(shè)置作用域(具體沒(méi)有實(shí)驗(yàn)過(guò))
參考來(lái)源
3.關(guān)于SpringMVC
SpringMVC的controller默認(rèn)是單例模式的,所以也會(huì)有多線程并發(fā)的問(wèn)題;
參考代碼:
@RequestMapping("/user") @Controller Class?UserController {@ResourceUserService?userService;@RequestMapping("/add")public?void?testA(User?user){userService.add(user);}@RequestMapping("/get")public?void?testA(int?id){userService.get(id);} }@Service("userService") Class?UserService{public?static?Map<Integer,User>?usersCache?=?new?HashMap<String,User>();public?void?add(User?user){usersCache.put(user.getId(),user);}public?void?get(int?id){usersCache.get(id);}}usersCache就是非線程安全的。
解決方法:
1)同步共享數(shù)據(jù)
2)不使用成員實(shí)例變量;
3)使用只讀數(shù)據(jù)
參考文章:
深入研究Servlet線程安全性問(wèn)題
Struts的線程安全問(wèn)題
深入研究Servlet線程安全性問(wèn)題
轉(zhuǎn)載于:https://my.oschina.net/Tonyjingzhou/blog/514345
總結(jié)
以上是生活随笔為你收集整理的关于java Servlet,Struts,springMVC 的线程安全问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SQL查询下级节点
- 下一篇: 用Elm语言降低失败的风险