Spring:Singleton / session范围和并发

Spring bean的singleton / session范围是否要求必须同步对其所有字段的访问? 通过“synchronized”关键字或使用包“java.util.concurrent”中的某些类来说。

例如,这段代码不是线程安全的吗? (从这里复制/补充):

@Component @SessionScoped public class ShoppingCart { private List items = new ArrayList(); public List getAllItems() { return items; } public void addItem(Product item) { items.add(item); } } 

当您使用Spring容器中的singleton作用域时,表明从容器中检索bean的所有线程都将使用相同的实例。 因此,在这种情况下,项目的状态列表在线程之间共享和修改,您必须同步对列表的访问以保护您的应用程序免受ConcurrentModificationException

但是,Spring的通常做法是使用无状态对象构建应用程序,这些对象没有在应用程序的整个生命周期中都会发生变化的状态。

session范围的情况下,您可能不太可能看到并发问题,因为bean只能由当前登录的用户访问。 但是,有可能(至少在网络上)有多个请求进入同一个会话,在这种情况下,您需要采取相同的预防措施,就像bean是单身一样。

保护自己的最佳方法是尽量保持你的bean尽可能无状态。 如果你有一个需要状态的bean,你应该考虑使用prototype范围,每次从容器中检索一个新的bean实例。

只有该会话的用户才能访问此类,但ArrayList不是线程安全的,如本讨论中所示: http : //forums.sun.com/thread.jspa?threadID = 5355402

您需要确保您的类完全是线程安全的,因为SessionScoped将确保它仅由每个会话使用,因此一个会话无法访问它。

您可以查看本讨论中的评论以获取更多信息: http : //wheelersoftware.com/articles/spring-session-scoped-beans.html

基本上,对于启动会话的每个用户,将为该用户创建新的ShoppingCart并将其范围限定为该会话。

你的课程是线程安全的。 初始化

 private List items = new ArrayList(); 

是一个线程安全的初始化和

addItem(Product item)是一个primefaces操作,因此也是线程安全的。