Recipe6.4.Writing Thread-Safe Actions


Recipe 6.4. Writing Thread-Safe Actions

Problem

Your Action classes must operate correctly in a multi-threaded environment.

Solution

In 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 action
package 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);     } }

Discussion

A 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 Also

The 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.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net