鉴于生产中使用的现有代码库包含一个类A,该类包含一个方法,该方法使用setter填充另一个POJO类B的N个字段,并将POJO返回给调用者,并且假定B类的所有实例都不同只考虑两个字段,即N-2个字段在B类的所有实例中都是相同的,如果A类具有对B类的静态引用并且初始化B类的不改变的字段,那么是否会有任何性能提升在一个静态初始化块?这样,A类中每次调用时填充B类N个字段的方法现在只需要填充两个不同的字段。这也将消除为每次调用A类中的方法创建类型B的新对象的需要。这种方法在多线程应用程序中有什么含义?
或者,我们可以声明B类中不会更改为静态的所有字段,以便A类中的方法仅设置每次调用更改的字段。无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?
示例:
class A {
private static B b = new B();
static {
b.setSystem("MySystem");
b.setVersion("1.1");
}
public B getB(String name) {
b.setName(name);
return B;
}
}
答案 0 :(得分:2)
鉴于B类的所有实例仅在两个字段
方面有所不同
所以我知道你有多个B
的实例这也消除了为每次调用A类方法创建类型B的新对象的需要。
但是现在你只有一个B实例 - 如果A更改了这两个字段,代码中所有引用该B实例的位置都会看到更改(假设正确同步)。
=>目前尚不清楚您是否需要一个或多个B实例。
这种方法在多线程应用程序中有什么含义?
如果您共享B个交叉线程的相同实例,则需要确保在编写和读取B的属性时使用正确的同步。
或者,我们可以声明B类中不会更改为静态
的所有字段
你的意思是最终?
无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?
它认为确实符合资格。特别是因为你似乎并不完全确定你需要什么。和往常一样的建议:简单易行。 IF 性能不够好,可以分析并确定代码的哪些部分需要改进。
如果您知道自己将处于多线程环境中,那么您应该避免任何静态和可变的事情 - 这将使您的生活更轻松并限制并发错误的风险。
理想情况下,(1)尽量不要在线程之间共享对象 - 如果你不能,那么(2)尝试共享不可变对象 - 如果你不能(3)确保你使用正确的同步并且你知道你在做什么。
答案 1 :(得分:0)
如果您只保留一个类B
的实例,您可以根据需要修改并返回该方法,那么您将不得不遇到麻烦:调用者不能依赖包含数据的返回对象请求。在单线程应用程序中,如果在两者之间存在对方法的不同调用,则存储该值并稍后访问它将导致麻烦。在多线程应用程序中,内容甚至可能在没有来自当前线程的调用的情况下发生更改,因为另一个线程可能会调用该方法并导致对象发生更改。对象甚至可能处于不一致状态。
在某些情况下,可以安全合理地使用它,但根据您提供的一般说明,我建议不要这样做。也许更好的解决方案是将B
类的不变部分分解出来,使B
仅保存两个变化的值,并引用另一个保持不可修改部分的对象。当然,这仅适用于您控制B
的实现。
答案 2 :(得分:0)
给定一个包含A类的方法,该方法使用setter
填充另一个POJO B类的N个字段
所以A有B的实例或B的实例列表?
并将POJO返回给调用者,并且假定B类的所有实例仅在两个字段方面不同,即N-2个字段在所有B类实例中都是相同的,
为什么不直接初始化B本身的N-2
字段。
如果类A具有对类B的静态引用并初始化在静态init块中没有更改的类B的字段,那么会有任何性能提升吗?这样,A类中每次调用时填充B类N个字段的方法现在只需要填充两个不同的字段。这也将消除为每次调用A类中的方法创建类型B的新对象的需要。这种方法在多线程应用程序中的含义是什么?
如果您使用Static
,则B将成为A
类的一部分,而不是A
的对象,因此对于所有A
个实例,B是否通用?您真的想要吗?
或者,我们可以声明B类中不会更改为静态的所有字段,以便A类中的方法仅设置每次调用更改的字段。无论哪种方式,性能增益是否值得,或者这种变化是否属于过早优化?
请提供一些代码。 在我看来,静态块应仅用于配置对象初始化。