说 DocumentService 类是不可变的,因为不可能改变它的两个字段中的任何一个(它们是只能由容器本身初始化一次的 spring bean),这样说是否正确?
根据不变性的定义 http://en.wikipedia.org/wiki/Immutable_object,正式来说,这个类是不是一成不变的.
如果一个对象的状态不可能改变,那么该对象就是不可变的,并且documentGenerationService
and documentPublishService
是班级状态的一部分 DocumentService
.
结果,如果班级有always相同的状态,它的行为always一样的方法。换句话说,没有办法改变不可变对象的行为,因为对象的行为仅取决于其状态,而在不可变对象中,该状态永远不会改变(不可变对象的示例是字符串和整数)。
请注意,在不变性的定义中,我们发现一个例外,其中“即使某些属性发生变化,但对象的状态发生变化,对象也被认为是不可变的[以及因此的行为]似乎没有改变 [...]”,但在这种情况下(根据提供的信息),引用状态的变化肯定会改变类的行为(因为我们无法控制它们自己的内部状态)。
有一个strategy http://download.oracle.com/javase/tutorial/essential/concurrency/imstrat.html使一个类不可变。您已经遵循了它的一些准则,但是如果您希望将其做到不可变(我认为情况并非如此),您将需要其他一些准则,例如 make“防御副本”您在构造函数中收到的参数和避免子类重写方法.
This link http://www.javapractices.com/topic/TopicAction.do?Id=29也很有趣。
尽管如此,你不应该使 Spring bean 不可变,因为这不是使用 Spring 提供的编程模型的方式。因此,在这种情况下,类不是不可变的,这是“好事”。
无论如何,上面定义的 DocumentService bean 可以被认为是线程安全的吗?
正如这里所声明的,这个类IS线程安全。许多线程可以安全地访问此类,而不会出现任何竞争条件。我们不能对它包含的字段说同样的话,但这个类是线程安全的。这与“线程安全列表”的工作方式相同:它可以包含“非线程安全”对象,但仍然是“线程安全列表”。
如果遵循这种设计,整个应用程序也是线程安全的吗?
如果系统的所有类都是线程安全的(即没有任何竞争条件出现在任何地方),您可以非正式地说应用程序是线程安全的。