struts 动作单例
为什么struts的action类是singleton的?
实际上我的意思是它是多线程的。但是当数千个请求命中相同的操作时,我们将同步用于防止线程问题,那么它不会提供良好的性能,因为线程处于等待状态并且需要时间来处理。
有什么方法可以从操作类中删除单例吗?
欲了解更多信息,请访问:http://rameshsengani.in
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您问的是为什么 Action 类是单例,但我认为您在理解线程安全性方面也存在一些问题,因此我将尝试解释两者。
首先,Struts Action 类不是作为单例实现的,框架仅使用它的一个实例。但由于仅使用一个实例来处理所有传入请求,因此必须注意不要在 Action 类中执行非线程安全的操作。但事实是:默认情况下,Struts Action 类不是线程安全的。
线程安全意味着一段代码或对象可以在多线程环境中安全地使用。 Action 类可以安全地在多线程环境中使用,并且您可以同时在一千个线程中使用它而不会出现任何问题......也就是说如果您正确实现它。
来自 Action 类 JavaDoc:
当您这样做时,您必须注意遵守上述规则。否:
您不需要同步 Action 类,除非您对它们做了错误,就像上面的代码一样,问题是您的操作的执行入口点是
execute
方法。接收它需要的所有内容作为参数。您可以在
execute
方法中同时执行一千个线程,不会出现任何问题,因为每个线程都有自己的方法执行堆栈。调用但不适用于在所有线程之间共享的堆中的数据(例如someInstanceField
)。如果修改
someInstanceField
时没有正确的同步,所有线程都会按照自己的意愿行事。所以,是的,Struts 1 Action 类不是线程安全的,但从某种意义上说,您不能安全地在其中存储状态(即使它们有状态),或者如果您这样做,则必须正确同步。
但是,如果您保持 Action 类实现无状态,那就没问题了,不需要同步,线程也不会相互等待。
这是设计使然。 JavaDoc 再次解释了这一点:
请求参数与 Web 层相关联,您不希望将该类型的数据发送到您的业务中逻辑类,因为这会产生紧密耦合
位于两层之间,这将使得您无法轻松地重用业务层。
因为将 Web 对象转换为模型对象(这里我不是指 ActionForm beans)应该是 Action 类的主要目的,所以它们不需要(也不应该)维护任何状态,而且,没有理由有更多这些人的例子,他们都在做同样的事情。只要一个就可以了。
如果您希望可以通过将信息保存到数据库来安全地维护模型中的状态,或者您可以使用 http 会话来维护 Web 状态。在 Action 类中维护状态是错误的,因为这引入了同步的需要,如上所述。
我想你可以扩展 Struts 并覆盖 RequestProcessor.processActionCreate 为每个请求创建一个 Action
但这意味着在 Struts 之上添加另一层来改变其“正常”行为。我已经在一些应用程序中看到过类似的问题,所以我不会推荐它。
我的建议是保持您的 Action 类无状态,并使用为其创建的单个实例。
如果您的应用程序是新的,并且您绝对需要有状态操作,我想您可以选择 Struts 2(他们更改了设计,现在每个请求一个操作实例)。
但是 Struts 2 与 Struts 1 有很大不同 因此,如果您的应用程序很旧,可能很难迁移到 Struts 2。
希望现在已经清楚了。
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:
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:
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 (likesomeInstanceField
) 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.
It's by design. Again the JavaDoc explains it:
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.
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.
这在 Struts2 中发生了变化 http:// struts.apache.org/release/2.1.x/docs/comparing-struts-1-and-2.html
*Struts 2 Action 对象针对每个请求进行实例化,因此不存在线程安全问题。 (实际上,Servlet 容器为每个请求生成许多废弃对象,多一个对象不会造成性能损失或影响垃圾收集。)*
This has changed in Struts2 http://struts.apache.org/release/2.1.x/docs/comparing-struts-1-and-2.html
*Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.) *
我对struts不太了解,但似乎 这在 Struts 2 中发生了变化,所以也许您应该切换到 Struts 2?
I don't know much about struts, but it appears that this changed in Struts 2, so perhaps you should switch to Struts 2?