Java @singletonbean是否应该返回一个内部列表<&燃气轮机;成员?
这可能是一个非常简单的问题,但我并不完全清楚 我有一个bean,如下所示:Java @singletonbean是否应该返回一个内部列表<&燃气轮机;成员?,java,java-ee-6,Java,Java Ee 6,这可能是一个非常简单的问题,但我并不完全清楚 我有一个bean,如下所示: @Singleton @Startup @Lock(READ) public class SomeDataBean { List<Foo> foos; @PostConstruct public void init() { // Build foos; } public List<Foo> getFoos() { return foos; } @L
@Singleton
@Startup
@Lock(READ)
public class SomeDataBean {
List<Foo> foos;
@PostConstruct
public void init() {
// Build foos;
}
public List<Foo> getFoos() {
return foos;
}
@Lock(WRITE)
public void modifyFoos() {
// This could be potentially called too
}
}
@Singleton
@启动
@锁(读)
公共类数据库{
列出食物;
@施工后
公共void init(){
//建立foos;
}
公共列表getFoos(){
返回foos;
}
@锁(写)
公共void modifyFoos(){
//这也可能被称为
}
}
随后,这个bean被注入(使用CDI-environment is Wildfly 8.2)到各种其他bean中(请求/会话/视图等),现在它们都可以访问这个Foo
s列表。我的问题是,当另一个bean可能调用modifyFoos()
时,按原样返回列表是否安全。或者这是一件永远不会发生的事情,并且是由容器保证的
我读过一些关于容器管理事务等的文档,但不完全清楚它在这种情况下是如何工作的。例如,用并发容器替换列表更好吗?不,这是不安全的,因为一个线程可以读取列表,而另一个线程可以修改它
modifyFoos
中存储列表的新实例如果您不希望列表数据被其他类更改,您可以返回一个副本,而不是原始列表的引用。@sgplait,大多数情况下我返回一个
Stream()
-我在示例中使用list
,因为它更通用一些。。。但同样的问题也适用于。。(好吧,流-除非由并发容器支持,否则不是线程安全的。!?!)要么返回列表的副本(防御副本),要么如果它是线程安全的,那么你就没有问题(迭代时也要小心,除非它是CopyOnWriteArrayList)。我希望得到一些容器魔法酱,啊,好吧,我会坚持退回副本。你能更具体地谈谈“容器魔法酱”吗?你也应该在那里使用一些同步。当你使用单例列表时,容器魔法帮不了你。如果与读相比,写是罕见的,那么您可以考虑选项3。对列表(或其他容器)的结构变化确实是罕见的。个人Foo
s已正确同步-问题更多的是返回原始列表是否安全-对于我而言,对客户不切实际的期望。。。