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