我正在处理一个问题,我需要将大量输入加载到问题中,并处理这些输入以创建“问题空间”(即构建允许有效访问输入的数据结构等)。一旦这个初始化完成,一个多线程进程就会启动,它以并发方式广泛使用组织/处理的输入。
出于性能原因,我不想在并发阶段锁定和同步所有读取操作。我真正想要的是一个不可变的对象,可以安全地被多个读者同时访问。
出于实际原因(可读性和可维护性),我不想让 InputManager 成为真正的不可变对象(即所有字段“最终”并在构造中初始化)。InputManager 将有许多数据结构(列表和映射),其中每个对象都有许多相互循环引用。这些对象被构造为“真正的”不可变对象。我不希望 InputManager 有 14 个参数的构造函数,但我确实需要 InputManager 类来提供问题空间的一致的只读视图。
我想要的是 Eric Lippert在这里讨论的“冰棒不变性”。
我采用的方法依赖于使用所有变异方法的“包可见性”,并在单个包中执行所有可变操作(即 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
}
}
如果我还不够清楚的话,总体思路是,我将在单个线程中构建 InputManager,然后将其传递给多个线程,这些线程将使用该对象进行并发工作。我想尽可能地执行这个“两阶段”可变/不可变对象生命周期,而不做太“可爱”的事情。寻找意见或反馈以更好地实现这一目标,因为我确信这不是一个不常见的用例,但我也找不到支持它的设计模式。
谢谢。