【问题标题】:Are Interceptors in Struts2 Thread UNsafe?Struts2 线程中的拦截器是不安全的吗?
【发布时间】:2012-03-26 19:54:38
【问题描述】:

我了解 Struts2 Action 类是线程安全的,因为这些操作被放入了值堆栈中。值堆栈又是动作上下文的一部分。由于动作上下文是线程本地的,所以存储在动作上下文中的值(包括值堆栈)对于每个线程都是唯一的。所以,Action 是线程安全的。

但是考虑一下拦截器:它们真的很有用,它们为程序员完成了所有那些乏味的小工作......比如验证、获取参数值等。但要考虑的是:拦截器可以在多个之间共享要求。那么这会使拦截器线程不安全吗?

带着这个问题,我尝试在网上浏览一些与这个问题相关的好文章。我发现了一篇非常好的文章,他们在其中明确提到了拦截器如何不是线程安全的示例。

网页是:http://www.bullraider.com/java/struts2/tutorials/interceptors-and-thread-safety

我从这篇文章中了解到,拦截器线程不安全的主要原因是拦截器只创建一次。即每个拦截器只有一个对象。因此,当一个 Interceptor 的 同一个实例在线程之间共享时,实例字段是不安全的。

在文章的最后提到,在某些情况下,即使是拦截器也是线程安全的。但他们没有提到任何此类案例。我上网寻找答案......但徒劳无功:(

谁能告诉我或提供一个链接,我可以在其中找到如何使拦截器线程安全(或者拦截器线程安全的场景是什么)?

【问题讨论】:

    标签: java struts2 thread-safety interceptor


    【解决方案1】:

    任何不使用实例字段或其他共享状态的拦截器都是线程安全的:

    例如,看看 all the built-in interceptors 解析 HTTP 请求参数和 cookie,进行日志记录、访问检查、异常处理:它们不使用可变状态的实例字段 (*),而只是在 ActionInvocation 实例上操作它们作为参数获取。

    (*) 有些确实有配置参数的实例字段,这些字段在 Struts 启动时(在单个线程中)设置,例如 ExceptionMappingInterceptor,或线程安全实例字段,例如 LoggingInterceptor 中的 Logger

    如果您打算编写自己的Interceptor,只需使用传入的ActionInvocation 参数和intercept() 方法中的局部变量即可。避免使用拦截方法 synchronized 或将内容放入 synchronized{} 块中的诱惑——这将造成 Struts 的拦截器单实例方法的瓶颈。

    回答cmets的问题:

    (1) 为什么为每个线程创建一个动作实例不会影响性能?或者是吗?

    使用现代 JVM,创建对象的成本可以忽略不计。如果您通过避免昂贵的初始化(例如通过不在操作内创建数据库连接,而是使用连接池。

    (2) 你是否建议永远不要使用默认的拦截器堆栈,并始终使用自定义拦截器堆栈(其中所有使用实例变量的未使用的拦截器都被删除)以便线程安全?

    我认为 Struts 2 附带和配置的任何默认拦截器都不是线程安全的。即使它们使用实例字段(因为它们要么仅用于配置,要么本身是线程安全的,如 Logger)。

    根据我的个人经验,只有在有充分理由的情况下才应该触摸/更改拦截器堆栈(内置拦截器的线程安全不是其中之一)。如果您更改堆栈,很多事情都会以意想不到的方式运行/中断 - 从长远来看,运行“default”或“paramPrepareParam”等内置堆栈之一可以节省很多挫败感。添加您自己的自定义拦截器通常比从现有堆栈中删除/重新排列拦截器的破坏性更小。

    【讨论】:

    • 谢谢。确实是一个非常翔实的答案。给你的 2 个问题:(1)你提出了一个很好的观点,将拦截方法放在同步块中是非常低效的。那么,为什么为每个线程创建一个动作实例不会影响性能?或者是吗? (2) 你是否建议永远不要使用默认的拦截器堆栈,并始终使用自定义拦截器堆栈(其中所有使用实例变量的未使用的拦截器都被删除)以便线程安全?
    • @BimanTripathy 我在答案中添加了我对您的两个问题的看法。请看一下:)
    • @PhilippReichart 所以我想我一直在使用“默认”拦截器堆栈并没有做任何愚蠢的事情。非常感谢分享这么多:)
    【解决方案2】:

    可能相关,ScopeInterceptor.java 类可能存在线程安全问题:Java Thread Safety Issue in Struts ScopeInterceptor class?

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多