Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
673 views
in Technique[技术] by (71.8m points)

multithreading - struts action singleton

Why is the struts action class is singleton ?

Actually I am getting point that it is multithreaded. but at time when thousand of request hitting same action, and we put synchronized for preventing threading issue, then it not give good performance bcoz thread going in wait state and it take time to proced.

Is that any way to remove singleton from action class ?

for more info Please visit : http://rameshsengani.in

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are asking about why the Action class is a singleton but I think you also have some issues understanding thread safety so I will try to explain both.

First of all, a Struts Action class is not implemented as a singleton, the framework just uses one instance of it. But because only one instance is used to process all incoming requests, care must be taken not to do something with in the Action class that is not thread safe. But the thing is: by default, Struts Action classes are not thread safe.

Thread safety means that a piece of code or object can be safely used in a multi-threaded environment. An Action class can be safely used in a multi-threaded environment and you can have it used in a thousand threads at the same time with no issues... that is if you implement it correctly.

From the Action class JavaDoc:

Actions must be programmed in a thread-safe manner, because the controller will share the same instance for multiple simultaneous requests. This means you should design with the following items in mind:

  • Instance and static variables MUST NOT be used to store information related to the state of a particular request. They MAY be used to share global resources across requests for the same action.

  • Access to other resources (JavaBeans, session variables, etc.) MUST be synchronized if those resources require protection. (Generally, however, resource classes should be designed to provide their own protection where necessary.

You use the Struts Action by deriving it and creating your own. When you do that, you have to take care to respect the rules above. That means something like this is a NO-NO:

public class MyAction extends Action {
   private Object someInstanceField;
   public ActionForward execute(...) {
      // modify someInstanceField here without proper synchronization ->> BAD
   }
}

You don't need to synchronize Action classes unless you did something wrong with them like in the code above. The thing is that the entry point of execution into your action is the execute method.

This method receives all it needs as parameters. You can have a thousand threads executed at the same time in the execute method with no issues because each thread has its own execution stack for the method call but not for data that is in the heap (like someInstanceField) which is shared between all threads.

Without proper synchronization when modifying someInstanceField all threads will do as they please with it.

So yes, Struts 1 Action classes are not thread safe but this is in the sense that you can't safely store state in them (i.e.make them statefulf) or if you do it must be properly synchronized.

But if you keep your Action class implementation stateless you are OK, no synchronization needed and threads don't wait for one another.

Why is the struts action class is singleton ?

It's by design. Again the JavaDoc explains it:

An Action is an adapter between the contents of an incoming HTTP request and the corresponding business logic that should be executed to process this request

The request parameters are tied to the web tier and you don't want to send that type of data into your business logic classes because that will create a tight coupling between the two layers which will then make it impossible to easily reuse your business layer.

Because transforming web objects into model objects (and I don't mean the ActionForm beans here) should be the main purpose of Action classes, they don't need to maintain any state (and shoudn't) and also, there is no reason to have more instances of these guys, all doing the same thing. Just one will do.

If you want you can safely maintain state in your model by persisting info to a database for example, or you can maintain web state by using the http session. It is wrong to maintain state in the Action classes as this introduces the need for syncronisation as explained above.

Is there a way to remove singleton from action class?

I guess you could extend Struts and override the default behavior of RequestProcessor.processActionCreate to create yourself an Action per request but that means adding another layer on top of Struts to change its "normal" behavior. I've already seen stuff like this go bad in a few applications so I would not recommend it.

My suggestion is to keep your Action classes stateless and go for the single instance that is created for it.

If your app is new and you absolutely need statefull Actions, I guess you could go for Struts 2 (they changed the design there and the Action instances are now one per request). But Struts 2 is very different from Struts 1 so if you app is old it might be difficult to migrate to Struts 2.

Hope this makes it clear now.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...