【发布时间】:2011-04-13 13:38:07
【问题描述】:
为什么struts的动作类是单例的?
实际上我明白它是多线程的。但是当数千个请求达到相同的操作时,我们设置了同步以防止线程问题,然后它不能提供良好的性能 bcoz 线程进入等待状态并且需要时间来处理。
有没有办法从动作类中删除单例?
更多信息请访问:http://rameshsengani.in
【问题讨论】:
标签: multithreading struts
为什么struts的动作类是单例的?
实际上我明白它是多线程的。但是当数千个请求达到相同的操作时,我们设置了同步以防止线程问题,然后它不能提供良好的性能 bcoz 线程进入等待状态并且需要时间来处理。
有没有办法从动作类中删除单例?
更多信息请访问:http://rameshsengani.in
【问题讨论】:
标签: multithreading struts
您在问为什么 Action 类是单例的,但我认为您在理解线程安全方面也存在一些问题,因此我将尝试解释这两者。
首先,Struts Action 类不是作为单例实现的,框架只使用它的一个实例。但是因为只有一个实例用于处理所有传入的请求,所以必须注意不要在 Action 类中做一些非线程安全的事情。但问题是:默认情况下,Struts Action 类不是线程安全的。
Thread safety 表示一段代码或对象可以在多线程环境中安全使用。 Action 类可以安全地在多线程环境中使用,并且您可以让它同时在一千个线程中使用而不会出现任何问题...如果您正确实现它。 p>
必须以线程安全的方式对操作进行编程,因为控制器将为多个同时请求共享同一个实例。这意味着您在设计时应牢记以下几点:
实例和静态变量不得用于存储与特定请求状态相关的信息。它们可用于在同一操作的请求之间共享全局资源。
如果这些资源需要保护,则必须同步对其他资源(JavaBeans、会话变量等)的访问。 (不过,一般而言,资源类应设计为在必要时提供自己的保护。
您可以通过派生并创建自己的方式来使用 Struts Action。当你这样做时,你必须注意遵守上述规则。这意味着这样的事情是不可以的:
public class MyAction extends Action {
private Object someInstanceField;
public ActionForward execute(...) {
// modify someInstanceField here without proper synchronization ->> BAD
}
}
您不需要同步 Action 类,除非您在上面的代码中对它们做错了什么。问题是执行到您的操作的入口点是 execute 方法。
这个方法接收它需要的所有参数。您可以在 execute 方法中同时执行一千个线程而不会出现任何问题,因为 每个线程都有自己的执行堆栈用于方法调用,但对于堆中的数据(如someInstanceField) 在所有线程之间共享。
修改someInstanceField时如果没有适当的同步,所有线程都会随心所欲。
所以是的,Struts 1 Action 类不是线程安全的,但从某种意义上说,您不能在其中安全地存储状态(即使它们成为有状态),或者如果您这样做,则必须正确同步。
但是,如果您保持 Action 类实现无状态,您就可以,不需要同步并且线程不会相互等待。
为什么struts的action类是单例的?
这是设计使然。 JavaDoc 再次解释了它:
Action 是传入 HTTP 请求的内容和应执行以处理此请求的相应业务逻辑之间的适配器
请求参数与 Web 层相关联,您不希望将此类数据发送到业务逻辑类中,因为这会产生紧密耦合 在这两个层之间,这将使您无法轻松地重用您的业务层。
因为将 Web 对象转换为模型对象(我在这里不是指 ActionForm bean)应该是 Action 类的主要目的,所以它们不需要维护任何状态(并且不应该),而且还有没有理由有更多这些家伙的实例,都在做同样的事情。一个就够了。
如果您愿意,您可以通过将信息保存到数据库来安全地维护模型中的状态,或者您可以使用 http 会话来维护 Web 状态。在 Action 类中维护状态是错误的,因为这会引入如上所述的同步需求。
有没有办法从动作类中删除单例?
我猜你可以扩展 Struts 并覆盖 RequestProcessor.processActionCreate 的默认行为来为每个请求创建一个 Action 但这意味着在 Struts 之上添加另一层以改变其“正常”行为。我已经在一些应用程序中看到过这样的问题,所以我不推荐它。
我的建议是让您的 Action 类保持无状态,并使用为其创建的单个实例。
如果您的应用是新的,并且您绝对需要有状态的 Action,我想您可以选择 Struts 2(他们改变了那里的设计,现在每个请求一个 Action 实例)。 But Struts 2 is very different from Struts 1 因此,如果您的应用程序较旧,则可能难以迁移到 Struts 2。
希望这现在清楚了。
【讨论】:
这在 Struts2 http://struts.apache.org/release/2.1.x/docs/comparing-struts-1-and-2.html 中发生了变化
*Struts 2 Action 对象为每个请求实例化,因此不存在线程安全问题。 (在实践中,servlet 容器在每次请求时会生成许多丢弃的对象,多一个对象不会造成性能损失或影响垃圾收集。)*
【讨论】:
我对struts了解不多,但似乎this changed in Struts 2,所以也许你应该切换到Struts 2?
【讨论】: