我了解你提出问题的动机。在开始从事编译器工作之前,我也有一个非常相似的想知道Java虚拟机内部的知识。
首先,你的问题给我留下了深刻的印象。为了解决你的问题,需要有几点区别和理解。首先:Singleton模式(有时甚至称为反模式)确保JVM(Java虚拟机)只有该类的一个实例。这意味着我们实质上是在应用程序中引入全局状态。我知道你了解这一点,但这只是一个澄清点。
现在是内部。
创建类的实例时,我们将创建一个驻留在JVM共享内存中的对象。现在,这些线程正在独立执行在这些实例上运行的代码。每个线程都有一个工作内存,在其中保存所有线程之间共享的主内存中的数据。这是你创建的Singleton对象的引用所在的位置。本质上,正在发生的事情是在这些线程的每个线程上执行生成的字节码,该字节码代表你创建的单例对象。
现在,如何进行此操作的内部原理如下:
每个JVM线程都有一个专用JVM堆栈,与该线程同时创建。现在,JVM具有一个在所有JVM线程之间共享的堆。堆是运行时数据区,从中分配了所有类实例和数组的内存。堆是在VM启动时创建的。当你的线程请求单例实例时,它将指向此Singleton的字节码所在的堆中的引用。它将执行适当的代码。在你的情况下,它将对第一个请求执行第一个方法,对第二个请求执行第二个方法。之所以能够这样做,是因为没有锁或限制可以阻止编译器将程序计数器指向分配此实例的堆中的区域。Singleton类对Java虚拟机的唯一限制是,该类的堆中只能有一个实例。就是这样。除此之外,你可以从方法中引用它100次,编译器将指向相同的字节码并简单地执行它。这就是为什么我们通常希望Singleton类是无状态的,因为如果我们有任何线程访问它,由于缺少并发控制,我们不希望内部变量发生突变。
请让我知道,如果你有任何问题!



