Spring 中的线程
我有一个使用 spring、hibernate 和 struts 的 Web 应用程序(它在 Tomcat 上运行)
调用顺序是这样的...
Struts 操作调用 spring 服务 bean,后者又调用 Spring DAO bean。 DAO 实现是 Hibernate 实现。
问题是 我所有的 spring bean 都会在同一个线程中运行吗? 我可以在 ThreadLocal 中存储一些内容并在另一个 bean 中获取它吗?
我很确定这在无状态会话 Bean 中不起作用。 EJB 容器可以(或将会)为会话 bean 的每次调用生成一个新线程
Spring 容器也会做同样的事情吗? 即在同一个线程中运行所有bean?
当我尝试JUnit测试时 - 我通过测试用例中的Thread.currentThread().getId()获得了相同的id和两个bean - 这让我相信那里只有一个线程在运行
或者行为是不可预测的吗? 或者在Tomcat服务器上运行时它会改变吗?
澄清 我不想在两个线程之间交换数据。 我想将数据放入 ThreadLocal 中,并能够从调用堆栈中的所有 bean 中检索它。 仅当所有 bean 都在同一线程中时这才有效
I have a Web application using spring and hibernate and struts (it runs on Tomcat)
The call sequence is something like this...
Struts action calls spring service bean which in turn calls Spring DAO bean. The DAO implementation is a Hibernate implementation.
The question is
Would all my spring beans be running in the same thread ?
Can I store something in the ThreadLocal and get it in another bean?
I am quite sure this would not work in Stateless Session Bean.
The EJB container can (or will) spawn a new thread for every call to the session bean
Will the spring container do the same? i.e. run all beans in the same thread ?
When I tried a JUnit test - I got the same id via Thread.currentThread().getId() in the Test Case and the two beans- which leads me to believe there was only one thread in action
Or is the behavior unpredictable?
Or will it change when running on Tomcat server ?
Clarification
I do not wish to exchange data between two threads. I want to put data in the ThreadLocal and be able to retrieve it from all beans in the call stack. This will work only if all beans are in the same thread
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Spring 不会产生线程。 汤姆猫确实如此。 Spring 只是为您创建和连接对象。
来自浏览器的每个请求都在一个请求中处理。 处理该请求的是 Tomcat。 是Tomcat创建了线程来处理请求。
假设您刚刚在 Spring 中创建了一个名为“X”的单例 bean。 那么所有请求都会使用同一个 X 实例。
Spring bean 并不存在于线程中。 它们只是分配在堆上。
Spring doesn't spawn the threads. Tomcat does. Spring is just creating and wiring up the objects for you.
Each request from the browser is processed in one request. It is Tomcat that handles the request. It is Tomcat that creates the thread to process the request.
Assuming you have just created a singleton bean in Spring called "X". Then the same instance of X is used by all requests.
The Spring beans don't live in a thread. They are just allocated on the heap.
对于大多数网络应用程序,每个新请求都会生成一个新线程,如果您想在两个请求之间共享数据,通常:
- 使用get/post参数传递数据
- 使用会话共享数据
为了回答你的问题,我很确定 spring 容器不会为大多数组件生成线程。
For most webapps, a new thread is spawned for each new request, and if you want to share data between two requests you normally:
- use the get/post parameters to pass the data
- use the session to share data
To answer your question, I'm pretty sure the spring container does not spawn threads for most components.
是的,你可以这样做。 相同的线程将用于执行您的操作,以便 ThreadLocal 能够工作。 通常,相同的线程也用于无状态会话 bean,假设它在同一个应用程序服务器实例中运行。 不过,我不会依赖于此,因为它可能依赖于供应商。
我们使用这种技术来访问代码中任何位置的调用者身份。 我们也使用会话 bean 和 jms,但在容器之间显式传递信息并在每个入口点设置 ThreadLocal。 这样,bean(会话或 mdb)是否是本地的并不重要。
Yes, you can do this. The same thread will be used to execute your action so the ThreadLocal will work. Typically, the same thread is used for the stateless session bean as well, assuming it is running in the same app server instance. I would not depend on this though, as it is probably vendor dependent.
We use this technique to access the callers identity anywhere in the code. We use session beans and jms as well, but explicitly pass the information between containers and set the ThreadLocal at each entry point. This way it doesn't matter if the bean (session or mdb) are local or not.
除了所有其他答案之外,我将添加以下内容:
通常切换线程的唯一原因是因为对并行性的某些要求。 由于这通常不会在复杂性方面免费出现,因此当发生这种情况时通常会清楚地通知您。
在看似单线程的请求处理中切换线程实际上非常复杂。 这通常只会发生在容器中的一处,并且通常由接收来自外部客户端的请求的 tcp/ip 套接字读取器处理。 这些读取器线程通常确定哪个线程(池)应该处理请求并将请求转发到该线程。 之后请求将保留在该线程中。
因此,通常唯一会/可能发生的事情是为并行或异步处理(如 JMS)创建额外的线程。
In addition to all the other answers, I will just add the following:
Normally the only reason to switch threads is because of some requirement for parallellity. Since this normally does not come for free in terms of complexity, you will usually be clearly informed when this happens.
Switching threads within what appears to be a single-threaded processing of a request is actually extremely complex. This will normally only happen at one place in a container, and this is usually handled by tcp/ip socket readers that receive the request from the external clients. These reader threads usually determine which thread(pool) should process the request and forward the request to that thread. After that the request stays with that thread.
So normally the only thing that will/can happen is that additional threads get created for parallelity or asynchronous processing (like JMS).