什么是 Java 中的无状态对象?

目前我正在阅读“ Java 并发实践”,其中包含这样一句话:

由于访问无状态对象的线程的操作不会影响其他线程上操作的正确性,因此无状态对象是线程安全的。

那么,什么是无状态对象?

60667 次浏览

无状态对象是没有实例字段(实例变量)的类的实例。类 有字段,但它们是编译时常量(static final)。

一个非常相关的术语是 永恒不变。不可变对象可能具有状态,但在调用方法时不会更改状态(方法调用不会将新值分配给字段)。这些对象也是线程安全的。

如果对象没有任何实例字段,则为 无国籍。如果它有一些字段,它也可以是无状态的,但是它们的值是已知的,并且不会改变。

这是一个 无国籍对象:

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);
}
}

没有状态的对象,如实例变量,它可以根据对象已经发生的变化而变化

无状态对象是没有任何内部状态(内部变量)的对象

如果对象完全没有状态,那么重用它们就没有问题 现在的问题是: 如果他们完全没有状态,为什么不让所有的方法都是静态的,而根本不创建一个呢?

无状态对象的概念与 副作用的概念高度耦合。 简而言之,这是一个没有字段的对象,这些字段根据不同的方法调用顺序可能具有不同的值。

只是澄清一下。 你可以像前面说的那样认为你的类是无状态的,即使它有一个实例变量,因为这个变量是 final AND 不可变的。

如果这个实例变量是 final 的但是可变的,例如一个字符串的列表,是的,变量的引用不能改变,但是列表的内容可以改变,因此类的状态可以改变。

如果您不能更改对象的任何参数或值等,在其创建之后,则该对象是线程安全的。

简单地说,对象的状态意味着该对象中内部变量的值。

对象的状态可以改变,意味着该对象成员变量的内部值可以改变

如何改变价值观?

通过设置值。

什么时候可以设置这个值? 当变量不是 final. 。

因此,为了使类无状态,将变量设置为 final,这样变量的值就不能在 setter 中更改,也不能在其他方法中更改。它只能用于计算。

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.