我正在研究一个问题,我需要将大量输入加载到问题中,并处理这些输入以创建“问题空间”(即构建允许高效访问输入的数据结构等)。一旦这个初始化完成,一个多线程进程就开始了,它以一种并行的方式广泛地使用了组织/处理过的输入。Java冰棍不可变
出于性能原因,我不想锁定并同步并发阶段中的所有读取操作。我真正想要的是一个不可变的对象,可以安全地同时访问多个阅读器。
出于实际的原因(可读性&可维护性)我不想让InputManager成为一个真正的不可变对象(即所有字段'最终'并在构造中初始化)。 InputManager将有许多数据结构(列表和映射),其中每个对象都有许多循环引用。这些对象被构造为'真实'不可变对象。我不想为InputManager有14个参数的构造函数,但我确实需要InputManager类来构造一个一致的,只读的问题空间视图。
什么我要为是“冰棍不变性”由埃里克利珀讨论here.
我采用的方法依赖于使用“包可见”所有的变异方法,并执行所有可变操作(即InputManager的构建)在一个包中。吸气者都有公众的知名度。
喜欢的东西:
public final class InputManager { // final to prevent making mutable subclasses
InputManager() { ... } //package visibility limits who can create one
HashMap<String,InputA> lookupTable1;
...
mutatingMethodA(InputA[] inputA) { //default (package visibility)
//setting up data structures...
}
mutatingMethodB(InputB[] inputB) { //default (package visibility)
//setting up data structures...
}
public InputA getSpecificInput(String param1) {
... //access data structures
return objA; //return immutable object
}
}
的总体思路,如果我没有得到足够清晰,我会构成输入管理在一个单独的线程,然后将它传递给多个线程谁做的并发使用该对象工作。我希望尽可能强制执行这个“两阶段”可变/不可变对象生命周期,而不要做太“可爱”的事情。寻找更好的方法来实现这个目标的意见或反馈,因为我相信这不是一个不常见的用例,但我找不到支持它的设计模式。
谢谢。
感谢所有的伟大答案。基于这些答案,我查看了番石榴的ImmutableCollections实现,这里的'builder'范例看起来非常像您提到的可变伴侣成语。我正在研究这个问题,试图决定在这个项目中是否值得在这一点上做出努力。谢谢! – BrianV
这里很好的讨论:(http://codereview.stackexchange.com/questions/11538/comments-on-my-java-pattern-for-mutable-turned-immutable-objects) – BrianV