【问题标题】:Thread safe class vs Utility class with all static methods线程安全类与具有所有静态方法的实用程序类
【发布时间】:2012-06-28 21:18:59
【问题描述】:

当我看到一个记录为线程安全的类时,我想知道为什么它没有被设计成一个包含所有静态方法(如 java.lang.Math 等)的实用程序类。

每当我在没有状态但在单个类中链接方法的场景中设计一个类时,我都缺少有效的驱动力。

示例 1:具有“线程安全字段”S 的类 A 怎么样?我的意思是,对象“S”本身是线程安全的。我们可以将类 A 中的所有方法和字段(如 S)声明为静态的吗?

我希望我的解释足够清楚。请说清楚。

注意:排除 javabean、属性持有类等。我的问题是关于基于输入参数执行某些操作的类,它们可能还需要使用其他类。

我很抱歉我编辑了这个问题。初稿完全模棱两可。

【问题讨论】:

  • Timer 为例——您将在哪里存储特定于实例的状态? (一个计时器与另一个不同。没有任何属性并不意味着没有状态。)

标签: java oop design-patterns object-oriented-analysis


【解决方案1】:

我可以很容易地想象一个类需要有状态的情况,但它也是线程安全的要求。例如,我将队列用于工作线程。它HAS 是线程安全的,并且肯定必须有状态。 (即队列中的元素)

编辑:

注意:排除 javabean、属性持有类等。我的问题是关于基于输入参数执行某些操作的类,它们可能还需要使用其他类。

如果你的意思是你的问题是关于真正无状态的类,那么 - 根据定义 - 你的观察是正确的。这些几乎总是可以用静态实用程序类来表达。

EDIT2:

我认为您在某种程度上被以下事实误导了,即很多时候当我们看到 static 时,我们可以对线程安全放心。 (尽管并非在所有情况下都如此,这只是一个经验法则)虽然线程安全和无状态可以在某种程度上齐头并进,但静态是一个正交概念。此外,无状态确实为您提供线程安全,但线程安全并不一定意味着无状态。如果是这样的话,synchronized 的整个概念就没有必要了。

【讨论】:

  • 感谢您的回复。是的,我意识到我的问题有点模棱两可。我实际上专注于不需要任何状态的类。
  • 我不会说它们总是可以用静态实用程序类来表达。通常,它们需要扩展一个抽象类或实现一个接口,在对象之间进行实例化、存储和传递。以 Collections.EMPTY_LIST 为例。线程安全,没有状态,但它必须是一个列表。大多数 Comparator 实现都一样。
  • @Firefox:您能否更新问题以给出一个类的示例,该类被记录为线程安全但当时没有状态?计时器就是一个不好的例子。
  • @JBNizet:感谢您的更正,我相应地修改了我的答案
  • @JonSkeet 是的,我明白了。我正试图找到一个。我用一个不好的例子完全歪曲了我的怀疑。
【解决方案2】:

为了可测试性,因为static 适合 OO,就像拳头适合鼻子一样。

可测试代码要求您可以以受控方式创建测试对象。我不想仅仅因为它是从我正在测试的对象中的某个地方调用的,就必须执行某人的代码。我想单独测试我的对象 - 假设它的合作者工作正常。使用来自某些工具的静态方法使我使用 PowerMock 进行可测试性或吻隔离再见并在我测试时执行该代码。 Powermock 是个问题(因为它使用自己的类加载器),所以测试比我想要的要多。

静态意味着程序代码。有时这很好,因为程序有时很好。但是尝试使用带有静态方法的 OO 特性(继承、多态)来找到另一个不使用 static 的原因。 说明这一点的简单示例:http://www.javaworld.com/javaworld/javaqa/2001-05/01-qa-0504-oo.html?page=1 - 绝不是详尽无遗的,但说明了我希望的观点。 @JB Nizet 对上述答案的评论中列出了其他示例。

我知道这是一个迟到的答案,但老实说,我在使用“无实例”类中的静态方法和通常受欢迎的解决方案(即 PowerMock)测试对象时遇到了相当多的问题。

【讨论】:

    猜你喜欢
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 2015-03-24
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多