春天的主题

时间:2009-04-23 16:17:29

标签: java multithreading spring tomcat thread-local

我有一个使用spring和hibernate以及struts的Web应用程序(它在Tomcat上运行)

呼叫序列是这样的......

Struts动作调用spring服务bean,后者又调用Spring DAO bean。 DAO实现是一个Hibernate实现。

问题是 我的所有春豆都会在同一个线程中运行吗? 我可以在ThreadLocal中存储一些内容并将其放入另一个bean中吗?

我很确定这在无状态会话Bean中不起作用。 EJB容器可以(或将)为每次调用会话bean

生成一个新线程

弹簧容器会不会这样做?即在同一个线程中运行所有bean?

当我尝试JUnit测试时 - 我通过测试用例中的Thread.currentThread()。getId()和两个bean得到相同的id - 这让我相信只有一个线程在运行

或者这种行为是不可预测的? 或者在Tomcat服务器上运行时会改变吗?

澄清 我不希望在两个线程之间交换数据。我想将数据放在ThreadLocal中,并能够从调用堆栈中的所有bean中检索它。只有当所有bean都在同一个线程

时,这才有效

4 个答案:

答案 0 :(得分:15)

Spring不会产生线程。 Tomcat呢。 Spring只是为你创建和连接对象。

浏览器的每个请求都在一个请求中处理。是Tomcat处理请求。 Tomcat创建了处理请求的线程。

假设您刚刚在Spring中创建了一个名为“X”的单例bean。然后,所有请求都使用相同的X实例。

Spring bean不存在于一个线程中。它们只是在堆上分配。

答案 1 :(得分:1)

  

我所有的春豆都会跑   在同一个线程?我可以存储吗?   在ThreadLocal中得到的东西   它在另一个豆?   AFAIK为您提到的组件(服务bean,DAO bean - 我猜它们是普通的spring bean),Spring不会产生新的线程。我不明白你的用例(即在两个线程之间交换数据)。

对于大多数webapps,会为每个新请求生成一个新线程,如果要在两个请求之间共享数据,通常是:   - 使用get / post参数传递数据   - 使用会话共享数据

要回答你的问题,我很确定spring容器不会为大多数组件生成线程。

答案 2 :(得分:0)

是的,你可以这样做。将使用相同的线程来执行您的操作,以便ThreadLocal可以工作。通常,相同的线程也用于无状态会话bean,假设它在同一个应用服务器实例中运行。我不会依赖于此,因为它可能依赖于供应商。

我们使用此技术在代码中的任何位置访问调用者身份。我们也使用会话bean和jms,但是在容器之间显式传递信息并在每个入口点设置ThreadLocal。这样,bean(session或mdb)是否是本地的并不重要。

答案 3 :(得分:0)

除了所有其他答案之外,我将添加以下内容:

通常,切换线程的唯一原因是因为对并行性有一些要求。由于这通常不会在复杂性方面免费提供,因此通常会在发生这种情况时通知您。

在似乎是请求的单线程处理的情况下切换线程实际上非常复杂。这通常只发生在容器中的一个地方,这通常由接收外部客户端请求的tcp / ip套接字读取器处理。这些读取器线程通常确定哪个线程(池)应该处理请求并将请求转发给该线程。之后,请求将保留在该线程中。

通常,唯一能够/可能发生的事情是为并行或异步处理(如JMS)创建额外的线程。