java Spring:单例/会话范围和并发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1745790/
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
Spring: Singleton/session scopes and concurrency
提问by Alex Siman
Does singleton/session scopes of Spring beans require that access to all its fields must be synchronized? Say through "synchronized" keyword or using some classes from package "java.util.concurrent".
Spring bean 的单例/会话范围是否要求必须同步对其所有字段的访问?说通过“同步”关键字或使用包“java.util.concurrent”中的一些类。
As example, is this code not thread safe? (copy/pased from here):
例如,这段代码不是线程安全的吗?(从这里复制/粘贴):
@Component
@SessionScoped
public class ShoppingCart {
private List<Product> items = new ArrayList<Product>();
public List<Product> getAllItems() {
return items;
}
public void addItem(Product item) {
items.add(item);
}
}
回答by Jason Gritman
When you use singletonscope from the Spring container, you indicate that all threads that retrieve the bean from the container will use the same instance. So in this case, where the state list of item is shared and modifiable between threads, you would have to synchronize access to the list to protect your application against a ConcurrentModificationException.
当您使用singletonSpring 容器中的作用域时,您表示从容器中检索 bean 的所有线程都将使用相同的实例。因此,在这种情况下,项目的状态列表在线程之间共享和修改,您必须同步对列表的访问以保护您的应用程序免受ConcurrentModificationException.
However, the usual practice with Spring is to build your application with stateless objects, which don't have state that will be changing throughout the life of the application.
但是,Spring 通常的做法是使用无状态对象构建应用程序,这些对象没有在应用程序的整个生命周期中都会发生变化的状态。
In the case of sessionscope, you might be less likely to see a concurrency problem since the bean will only be accessible by the currently logged in user. However, it's possible (at least on the web) to have multiple requests coming in on the same session, in which case you would need to take the same precautions as if the bean were a singleton.
在session范围的情况下,您可能不太可能看到并发问题,因为该 bean 只能由当前登录的用户访问。但是,有可能(至少在 Web 上)在同一个会话中收到多个请求,在这种情况下,您需要采取与 bean 是单例相同的预防措施。
Again the best way to protect yourself is to try to keep your bean as stateless as possible. If you have a bean that requires state, you should consider using the prototypescope, which retrieves a new instance of the bean from the container each time.
同样,保护自己的最佳方法是尽量使 bean 无状态。如果你有一个需要状态的 bean,你应该考虑使用prototype作用域,它每次从容器中检索一个新的 bean 实例。
回答by James Black
Only the user for that session can access this class, but ArrayList is not thread-safe, as seen in this discussion: http://forums.sun.com/thread.jspa?threadID=5355402
只有该会话的用户可以访问此类,但 ArrayList 不是线程安全的,如本讨论中所示:http: //forums.sun.com/thread.jspa?threadID=5355402
You need to ensure that your class is fully thread-safe as SessionScoped will just ensure that it is only used by each session, so one session can't access it.
您需要确保您的类是完全线程安全的,因为 SessionScoped 只会确保它仅被每个会话使用,因此一个会话无法访问它。
You may want to look at the comments in this discussion for more info: http://wheelersoftware.com/articles/spring-session-scoped-beans.html
您可能想查看此讨论中的评论以获取更多信息:http: //wheelersoftware.com/articles/spring-session-scoped-beans.html
回答by non sequitor
Basically for every user that initiates a session a new ShoppingCartwill be created and scoped to that session per that user.
基本上,对于启动会话的每个用户,ShoppingCart将创建一个新的会话并将其范围限定为每个用户的会话。
Your class is thread-safe. The initialization
您的课程是线程安全的。初始化
private List<Product> items = new ArrayList<Product>();
is a thread-safe initialization and
是一个线程安全的初始化和
addItem(Product item)is an atomic operation and is also therefore thread-safe.
addItem(Product item)是原子操作,因此也是线程安全的。

