Now the mainstream Java front-end framework is: STRUTS1,STRUTS2,SPRINGMVC and the most basic servlet;
Some days ago a friend asked me this question and studied it:
1. About Struts1:
The Actionservlet used by Struts1 is singleton and is handled by this servlet for all. Do requests. Requestprocessor is also a single case.
Requestprocessor Method of 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; // This synchronization fast guarantees the action of the single case 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 ()) { &nbsP; 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); }
From the results can be known, is a single case, since it is a single case, if the use of the instance variable when the thread security problem;
2. About STRUTS2
We know that when we use struts2, we use Actioncontext, and we use the instance variables inside to let struts2 automatically match into objects. if it's not thread-safe, it's all over; so struts2 must be thread-safe , because struts instantiates an object every time a request is processed;
Oh, forget a situation, struts2+spring to manage injection time; If you set the action to Singleton mode, you will get a problem, you can set the action to prototype type, and another way is to set the scope (no experiment)
Reference sources
3. About SPRINGMVC
SPRINGMVC controller default is singleton mode, so there will be multi-threading concurrency problem;
Reference code:
@RequestMapping ("/user") @ControllerClass UserController{ @Resource UserService 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 is non-thread-safe.
Workaround:
1) Synchronizing shared data
2) Do not use member instance variables;
3) Use read-only data
Reference article:
In-depth study of servlet thread security issues
Thread safety issues with struts
In-depth study of servlet thread security issues
About thread safety issues with Java SERVLET,STRUTS,SPRINGMVC