目前我正在阅读“实践中的Java并发”,其中包含以下句子:
由于访问无状态对象的线程的操作不会影响其他线程上的操作的正确性,因此无状态对象是线程安全的。
那么,什么是无状态对象?
答案 0 :(得分:80)
无状态对象是没有实例字段(实例变量)的类的实例。类可能有字段,但它们是编译时常量(静态最终)。
一个非常相关的术语是 immutable 。不可变对象可能具有状态,但在调用方法时它不会更改(方法调用不会为字段分配新值)。这些对象也是线程安全的。
答案 1 :(得分:55)
如果对象没有任何实例字段,则无状态。如果它有一些字段,它也可以是无状态的,但它们的值是已知的并且不会改变。
这是一个无状态对象:
class Stateless {
void test() {
System.out.println("Test!");
}
}
这也是无状态对象:
class Stateless {
//No static modifier because we're talking about the object itself
final String TEST = "Test!";
void test() {
System.out.println(TEST);
}
}
此对象具有状态,因此不无状态。但是,它的状态只设置一次,并且以后不会改变,这种类型的对象称为不可变:
class Immutable {
final String testString;
Immutable(String testString) {
this.testString = testString;
}
void test() {
System.out.println(testString);
}
}
答案 2 :(得分:2)
没有状态的对象,例如可以根据对象已经发生的事情而改变和变化的实例变量
答案 3 :(得分:2)
无状态对象的概念与side effects的概念高度耦合。 简而言之,那就是下面没有字段的对象可能有不同的值,这取决于方法调用的不同顺序。
答案 4 :(得分:1)
无状态对象是没有任何内部状态(内部变量)的对象
答案 5 :(得分:1)
只是澄清一下。 您可以按照前面所述的方式将您的类视为无状态,即使它具有实例变量,只要此变量是最终的AND不可变。
如果实例变量只是final但是可变的,例如,一个字符串列表,是的,变量的引用是不能改变的,但是List的内容以及类的状态可以改变。
答案 6 :(得分:0)
一个完全没有状态的对象然后重用它们没有问题 在这一点上,问题是:如果他们完全没有状态,为什么不将所有方法都设置为静态并且根本不创建一个?
答案 7 :(得分:0)
如果您无法更改对象的任何参数或值等,则在创建对象后,该对象是线程安全的。
答案 8 :(得分:0)
简单来说,对象的状态表示该对象中内部变量的值。
有状态-可以更改对象的状态,这意味着可以更改该对象的成员变量内部的值
如何更改值?
通过设置值。
何时可以设置该值? 当变量不是最终变量时。
因此,要使类变为无状态,请将变量定为final,以便既不能在setter中也不能在另一个方法中更改该变量的值。它只能用于计算。
答案 9 :(得分:0)
Stateless: it has no fields and references no fields from other classes.
特定计算的状态仅存在于局部变量中,这些局部变量存储在线程的堆栈中,并且只有执行线程才能访问。
一个线程访问一个方法/类不能影响另一个线程访问相同的方法/类的结果;因为两个线程不共享状态,所以好像它们正在访问不同的实例。
Since the actions of a thread accessing a stateless object cannot
affect the correctness of operations in other threads, Stateless objects are threadsafe.