|
Recipe 6.4. Writing Thread-Safe ActionsProblemYour Action classes must operate correctly in a multi-threaded environment. SolutionIn your custom Action, never use instance variables to carry per-request state; only use local variables. If you want to have local methods called from the execute() method, pass values to these methods as arguments instead of using instance variables. The Action class in Example 6-3 demonstrates this approach. Example 6-3. Thread-safe actionpackage com.oreilly.strutsckbk.ch06; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class ThreadSafeAction extends Action { // This variable is not thread-safe private SecurityUtil securityUtil = new SecurityUtil.instance( ); public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // the 'user' variable is thread-safe User user = (User) request.getSession( ).getAttribute("user"); // pass the user to the private method doSomething(user); // ... return mapping.findForward("success"); } private void doSomething(User user) throws Exception { // authenticate the user securityUtil.authenticate(user); } } DiscussionA Struts Action is subject to the same threading issues as a servlet. Internally, Struts maintains and reuses each Action instance to service requests. Your Action's execute( ) method will probably be called by multiple concurrent threads. You might be tempted to synchronize the execute() method, but avoid this temptation! Synchronizing the execute( ) method will degrade performance and you should avoid it. If you need to synchronize behavior in your application, perform the synchronization in the service layer of your application. If you use a base Action, as described in Recipe 6-1, you need to follow these guidelines. A base Action should refrain from using client-state instance variables like any other well-behaved Action class. See AlsoThe Struts User's guide addresses this specific issue, and other Action class design guidelines, in the section at http://struts.apache.org/userGuide/building_controller.html#action_design_guide. A recent JavaWorld article, "Writing thread-safe Servlets" by Phillip Bridgham, discusses this issue with respect to servlets and can be found at http://www.javaworld.com/javaworld/jw-07-2004/jw-0712-threadsafe.html. You can find discussions in the archives of the Struts user and developer mailing lists. |
|