【问题标题】:Thread Local questions in web environment在 Web 环境中讨论本地问题
【发布时间】:2013-02-05 05:30:58
【问题描述】:

我知道每个请求都由一个 servlet 线程提供服务,但是一个用户会话是否可能由两个不同的线程提供两个请求?

如果上述情况真的发生,那么第一个请求服务线程存储的线程局部变量被第二个请求服务线程读取怎么办?

恐怕如果我将用户凭据存储在第一个线程的 Spring Security 的 SecurityContextHolder(它使用线程局部变量)中,第二个线程将无法访问用户凭据...

【问题讨论】:

    标签: java multithreading servlets thread-local


    【解决方案1】:

    我知道每个请求都由一个 servlet 线程提供服务,但是一个用户会话是否可能由两个不同的线程提供两个请求?

    是的,这是可能的。

    恐怕如果我将用户凭据存储在第一个线程的 Spring Security 的 SecurityContextHolder(它使用线程局部变量)中,第二个线程将无法访问用户凭据...

    Spring 为每个请求单独建立安全性,您不必自己处理。

    【讨论】:

    • “Spring 为每个请求单独建立安全性”是什么意思?我只能在 Spring Security 的源代码中看到 ThreadLocal...
    • 是的,它使用了 ThreadLocal,但是 Spring Security 为每个请求单独设置。
    • 似乎 SecurityContextPersistenceFilter 具有魔力。谢谢
    【解决方案2】:

    不,一个请求不会由多个线程处理。真正可能发生的是一个线程处理 2 个请求。这就是您自己使用线程局部变量时应该非常小心的原因。但是,您可以信任 Spring 框架:它做的事情是正确的。例如,在使用线程本地时可以使用会话或请求 ID,因此不会混淆由一个线程处理的 2 个请求。

    【讨论】:

      【解决方案3】:

      同一用户的两个单独请求(很可能)由两个不同的线程处理。

      我不确定 Spring 做了什么,但 Servlet api 提供了一种检索特定于用户会话的数据的方法(服务器如何跟踪会话无关紧要,但请查看 cookie 和 url 重写)。

      现在,如果我想将用户凭据保存在 threadlocal 变量上(这并不罕见,因为 ThreadLocal 伪单例是我所知道的最方便的注入方式),我会将它们存储在用户 HttpSession 中(其中在同一用户的所有请求中是持久的)并使用 servlet 过滤器将它们放在每个请求开始时的 threadlocal 上。

      我希望这能让你更清楚一点。我发现即使使用最新的框架,也最好了解幕后发生的事情:)

      【讨论】:

        猜你喜欢
        • 2013-11-28
        • 1970-01-01
        • 1970-01-01
        • 2012-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-19
        相关资源
        最近更新 更多