关于java Servlet,Struts,springMVC 的线程安全问题
2019獨角獸企業重金招聘Python工程師標準>>>
現在主流的java的前端框架有:struts1,struts2,springmvc 還有最根本的servlet;
前些天一個朋友問我這方面的問題,就研究一番:
1.關于struts1:
Struts1使用的ActionServlet是單例的,由這一個servlet處理所有.do請求。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;//?這個同步快保證了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);}從結果可以知道,是單例,既然是單例,如果當使用實例變量的時候就會有線程安全的問題;
2.關于struts2
我們知道我們使用struts2的時候,都是使用actionContext ;都是使用里面的實例變量,讓struts2自動匹配成對象的。如果不是線程安全那全完了;所以struts2必須是線程安全的;因為每次處理一個請求,struts就會實例化一個對象;這樣就不會有線程安全的問題了;
哦,忘記了一種情況,struts2+spring來管理注入的時候;如果把action設置為單例模式,就會出現問題;可以把action設置為prototype類型,還有一個辦法是設置作用域(具體沒有實驗過)
參考來源
3.關于SpringMVC
SpringMVC的controller默認是單例模式的,所以也會有多線程并發的問題;
參考代碼:
@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)同步共享數據
2)不使用成員實例變量;
3)使用只讀數據
參考文章:
深入研究Servlet線程安全性問題
Struts的線程安全問題
深入研究Servlet線程安全性問題
轉載于:https://my.oschina.net/Tonyjingzhou/blog/514345
總結
以上是生活随笔為你收集整理的关于java Servlet,Struts,springMVC 的线程安全问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL查询下级节点
- 下一篇: 用Elm语言降低失败的风险