Struts1線程不安全
/**
* <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 class
instance = (Action) actions.get(className);
if (instance != null) {
if (log.isTraceEnabled()) {
log.trace(" Returning existing Action instance");
}
return (instance);
}
// Create and return a new Action instance
if (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);
}
在一個應用的生命周期中陵刹,Struts框架只會為每個Action類創(chuàng)建一個Action實例(與servlet是一樣的)。所有的客戶請求共享一個Action實例欢嘿,并且所有請求線程可以同時執(zhí)行它的execute()方法衰琐。
所以,每個action只有一個實例际插, 在action打印this也可以看到碘耳, 確實是一樣的,
所以框弛,
不要在Action里面使用全局變量記憶數(shù)據(jù), 沒有意義而且不安全
Struts2線程安全
因為每次處理一個請求捕捂,struts就會實例化一個對象
如果在spring注入action時使用了單例瑟枫,也會導致線程不安全
對于使用過SpringMVC和Struts2的人來說,大家都知道SpringMVC是基于方法的攔截指攒,而Struts2是基于類的攔截慷妙。
對于Struts2來說,因為每次處理一個請求允悦,struts就會實例化一個對象膝擂;這樣就不會有線程安全的問題了;
而Spring的controller默認是Singleton的,這意味著每一個request過來隙弛,系統(tǒng)都會用原有的instance去處理架馋,這樣導致兩個結果:
一是我們不用每次創(chuàng)建Controller,二是減少了對象創(chuàng)建和垃圾收集的時間;由于只有一個Controller的instance全闷,當多個線程調用它的時候叉寂,它里面的instance變量就不是線程安全的了,會發(fā)生竄數(shù)據(jù)的問題总珠。
servlet和springmvc都是線程不安全
<b>如果要讓struts1屏鳍,springmvc勘纯,servlet都變成線程安全該怎么做<b/>
1.與Spring集成@Scope("prototype"),對應每次請求產(chǎn)生一個新的action實例钓瞭。
2.加鎖
當然這些討論都針對實例變量驳遵,如果action中共享的是靜態(tài)變量,單例不單例都線程不安全了山涡。