我认为您必须区分已经存储在内存和代码执行之间。
在 单例对象中, 您具有:
- 字段 :它们存储在内存中。它们可以在多个线程之间共享,并且您不能保证它们会保持一致(除非您使它们保持 同步 )。
- 要调用的方法 :可以从多个线程中 调用 它们。每次执行都是独立的并且是线程安全的,除非它们 不正确地 访问某些共享字段。
现在来提一个问题:如果您在多个线程之间共享您的Singleton对象并同时访问它,则每个单个线程都将执行Singleton对象的代码部分,并包装在自己的执行中。
另外,如果编写的a
Thread.currentThread().getId();基本上返回正在执行的线程ID的单例方法,则将获得不同的id,因为不同的线程正在执行自己的方法堆栈。作为
无国籍 意味着你已经没有字段到单到他们之间可以共享!
关于无状态和有状态
无状态
意味着Bean没有可共享的字段。这意味着您的对象中仅包含方法或静态对象,因此您可以在任何地方使用它们,并且始终会返回相同的结果。您不必担心同步对字段的访问。
这是有关 无状态 的基本示例,假设您有一个仅执行 求和 运算的类:
public class StatelessClass{ public int sum(int a, int b){ return a+b; }}以相同的方式,您可以将其声明为 抽象 类(本身不能实例化),并将其方法设为 static ,这意味着您不需要它的任何实例即可调用其方法:
public abstract class StatelessClass{ public static int sum(int a, int b){ return a+b; }}然后,您可以将其用作
StatelessClass.sum(1,1);,这实际上与拥有一个 Singleton
对象本身非常相似,不同之处在于在Singleton中,您有一个唯一实例在应用程序中共享。
以相同的方式,具有被注入并提供对服务的访问的字段都不认为会改变对象的状态:
public class StatelessServiceClass{ private Service service; public int sum(int a, int b){ return service.sum(a,b); } public void setService(Service serv){ this.service=serv; }}但是,具有可修改的字段会使对象成为 有状态的 :
public class StatefulClass{ //This fields make the object STATEFUL private int totalSum = 0; public int sum(int a, int b){ int sum = a + b; totalSum = totalSum + sum; if (totalSum > 100) System.out.println("This thread "+Thread.currentThread().getId()+ +" got it!"); return sum; }}由于
sum可以同时被多个线程访问,因此您应确保
totalSum以同步方式进行访问。除非您这样做,否则不能保证印刷的句子为真。



