0

假设生产中使用的现有代码库包含一个类 A,该类 A 包含一个方法,该方法使用 setter 填充另一个 POJO 类 B 的 N 个字段并将 POJO 返回给调用者,并且假设类 B 的所有实例将仅在以下方面有所不同两个字段,即 N - 2 个字段在 B 类的所有实例中都是相同的,如果 A 类具有对 B 类的静态引用并初始化 B 类的字段在静态中不变初始化块?这样,在每次调用时填充类 B 的 N 个字段的类 A 中的方法现在只需填充两个不同的字段。这也将消除为每次调用类 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;

     }
}
4

3 回答 3

2

鉴于 B 类的所有实例仅在两个字段方面都不同

所以我知道你有不止一个 B 实例

这也将消除为每次调用类 A 中的方法创建一个类型 B 的新对象的需要。

但是现在您只有一个 B 实例 - 如果 A 更改了这两个字段,则代码中所有引用该 B 实例的位置都会看到更改(假设正确同步)。

=> 不清楚您是否需要一个或多个 B 实例。

这种方法在多线程应用程序中的含义是什么?

如果跨线程共享同一个 B 实例,则需要确保在写入和读取 B 的属性时使用正确的同步。

或者,我们可以将类 B 中所有不会更改的字段声明为静态

你的意思是决赛?

无论哪种方式,性能提升是否值得,或者这种变化是否符合过早的优化?

它认为它确实符合条件。特别是因为你似乎还不能 100% 确定你需要什么。所以和往常一样的建议:走简单的路。如果性能不够好,分析并确定代码的哪些部分需要改进。

如果您知道您将处于多线程环境中,您可能应该避免任何静态和可变的 - 这将使您的生活更轻松并限制并发错误的风险。

理想情况下,(1)尽量不要跨线程共享对象——如果你不能,那么(2)尝试共享不可变对象——如果你不能(3)确保你使用正确的同步并且你知道你在做什么是做。

于 2012-09-05T09:15:30.577 回答
0

给定一个包含方法的类 A,该方法使用 setter 填充另一个 POJO 类 B 的 N 个字段

所以 A 有 B 的实例或 B 的实例列表?

并将 POJO 返回给调用者,并假设 B 类的所有实例仅在两个字段方面是不同的,即 N - 2 个字段在 B 类的所有实例中都是相同的,

为什么不直接N-2在 B 本身初始化 Fields。

如果 A 类具有对 B 类的静态引用并初始化 B 类的在静态 init 块中不变的字段,是否会有任何性能提升?这样,在每次调用时填充类 B 的 N 个字段的类 A 中的方法现在只需填充两个不同的字段。这也将消除为每次调用类 A 中的方法创建一个类型 B 的新对象的需要。这种方法在多线程应用程序中的含义是什么?

如果你使用Static,那么 B 将是A类的一部分,而不是对象,A所以 B 对所有A实例都是通用的,你真的想要吗?

或者,我们可以将 B 类中所有不会更改的字段声明为静态,以便 A 类中的方法仅设置每次调用更改的字段。无论哪种方式,性能提升是否值得,或者这种变化是否符合过早的优化?

请提供一些代码。在我看来,静态块应该只用于配置对象的初始化。

于 2012-09-05T09:21:41.800 回答
0

如果您只保留一个 class 实例B,并根据需要修改并从该方法返回,那么您将不得不期待麻烦:调用者不能依赖包含他请求的数据的返回对象。在单线程应用程序中,如果在两者之间对方法进行不同的调用,则存储该值并稍后访问它会导致麻烦。在多线程应用程序中,内容甚至可能在没有来自当前线程的这种调用的情况下发生变化,因为另一个线程可能会调用该方法并导致对象发生变化。该对象甚至可能处于两者之间的不一致状态。

可能在某些情况下可以安全合理地使用它,但根据您提供的一般描述,我建议不要这样做。也许更好的解决方案是以只保存两个变化的值和对另一个对象的引用B的方式来分解类的不变部分,该对象包含不可修改的部分。B当然,这仅适用于您控制B.

于 2012-09-05T09:15:21.400 回答