Java Spring AMQP Listener Container 中的并发是如何实现的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23341811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How is concurrency in Spring AMQP Listener Container implemented?
提问by Parobay
My container XML config:
我的容器 XML 配置:
<rabbit:listener-container
connection-factory="myConnectionFactory"
acknowledge="none"
concurrency="10"
requeue-rejected="false">
<rabbit:listener ref="myListener" queues="myQueue"/>
</rabbit:listener-container>
and myListener
is just a class
并且myListener
只是一个类
@Component("myListener")
public class MyListener implements MessageListener {
@Autowired
SomeDependency dependency;
....
}
I've specified concurrency="10"
in my XML. What does this mean exactly?
我已经concurrency="10"
在我的 XML 中指定了。这是什么意思完全相同?
I've found some docs. They are not that helpful stating:
我找到了一些文档。他们不是那么有帮助,说明:
Specify the number of concurrent consumers to create. Default is 1.
指定要创建的并发消费者的数量。默认值为 1。
What I am interested in is whether MyListener
has to be thread safe i.e.
我感兴趣的是是否MyListener
必须是线程安全的,即
- are there many instances created or single instance used by many threads?
- can I access instance fields w/o synchronization?
- is
SomeDependency dependency
instantiated once or for each thread/instance? - does
dependency
need to be thread safe?
- 是否创建了多个实例或多个线程使用单个实例?
- 我可以在没有同步的情况下访问实例字段吗?
- 是
SomeDependency dependency
实例化一次还是为每个线程/实例实例化? - 是否
dependency
需要线程安全?
采纳答案by Gary Russell
Yes, to use concurrency, your listener has to be thread-safe. There is one listener instance per container. However, the <rabbit:listener-container/>
namespace element is actually just a convenience for adding "shared" attributes, each listener element gets its own container.
是的,要使用并发,您的侦听器必须是线程安全的。每个容器有一个侦听器实例。但是,<rabbit:listener-container/>
namespace 元素实际上只是为了方便添加“共享”属性,每个侦听器元素都有自己的容器。
It's generally best to use stateless objects (no fields that are written to), but that's not always possible.
通常最好使用无状态对象(没有写入的字段),但这并不总是可行的。
If your listener is not thread-safe, you can use...
如果您的侦听器不是线程安全的,您可以使用...
<rabbit:listener-container
connection-factory="myConnectionFactory"
acknowledge="none"
requeue-rejected="false">
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
<rabbit:listener ref="myListener" queues="myQueue"/>
...
</rabbit:listener-container>
...and add @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
. You will then get a container for each listener and a different instance of the listener will be injected into each.
...并添加@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
. 然后,您将为每个侦听器获取一个容器,并且每个侦听器的不同实例将被注入。
You will also need prototype scope for any non-thread-safe dependencies injected into the listener.
对于注入侦听器的任何非线程安全依赖项,您还需要原型作用域。