单例 Bean 如何服务并发请求?
我有一个关于单例 bean 如何详细处理并发请求的问题.
I have a question regarding how singleton beans serve concurrent requests in detail.
我在 StackOverflow 上搜索过这个问题.这是一个示例来自stackoverflow的链接,但我只找到了高级细节.我想要关于单例 bean 如何处理并发请求以及系统处理器如何查看这些请求的完整详细信息.
I have searched on StackOverflow regarding this question. This is a sample link from stackoverflow, but I found only high level details. I want full details on how a singleton bean serves concurrent requests and how the system processor will see those requests.
我在线研究了系统处理器中的并发请求处理.他们说处理器本身有一个调度器,调度器将决定处理哪个请求.
I have researched regarding concurrent request handling in the system processor online. They said the processor itself has a scheduler and that scheduler will decide which request gets processed.
好的.如果假设我有多个核心处理器,调度器如何处理并发请求?
Ok fine. If suppose I have more than one core processor, how does the scheduler handle concurrent requests?
谁能向我解释一下单例 bean 如何在 JVM 和系统中为并发请求提供服务的分步过程?
Can anyone explain to me the step-by-step process on how a singleton bean will serve concurrent requests in the JVM and system?
让我用一个具体的例子来解释.我有一个像 Sports
这样的课程:
Let me explain with a concrete example. I have a class like Sports
:
class Sports {
public void playFootball() {
}
public void playVolleyBall() {
}
}
有两个请求进来.第一个请求是在 Sports
类的已创建单例实例上执行 playFootball
方法.同时,另一个请求正在对 Sports
类的同一个已创建单例实例执行 playVolleyBall
方法.
Two requests come in. The first request is executing the playFootball
method on the created singleton instance of class Sports
. At the same time, another request is executing the playVolleyBall
method on the same created singleton instance of class Sports
.
单例实例怎么可能?
推荐答案
Saravan Kumar,
Saravan Kumar,
我了解您提出问题的动机.在我开始研究编译器之前,我也有一个非常相似的想了解 Java 虚拟机的内部结构.
I understand the motivation behind your question. Before I started working on compilers, I also had a very similar wanting to know the internals of the Java Virtual Machine.
首先,我对你的问题印象深刻.为了解决您的问题,需要有几点区别和理解.首先:单例模式,有时甚至称为反模式,确保只有一个此类的实例可用于 JVM(Java 虚拟机).这意味着我们本质上是将全局状态引入应用程序.我知道你明白这一点,但这只是一个澄清点.
First of all, I'm impressed by your question. There needs to be a couple of points of distinctions and understanding in order to solve your question. Firstly: A Singleton pattern, or sometimes even called an anti-pattern, ensures that there is only one instance of this class available to the JVM(Java Virtual Machine). This means we are essentially introducing a global state into an application. I know you understand this, but it is just a point of clarification.
现在是内部结构.
当我们创建一个类的实例时,我们正在创建一个驻留在 JVM 共享内存中的对象.现在,这些线程正在独立执行对这些实例进行操作的代码.每个线程都有一个工作内存,它保存所有线程之间共享的主内存中的数据.这是对您创建的 Singleton 对象的引用所在的位置.本质上,正在发生的事情是生成的代表您创建的单例对象的字节码正在这些线程中的每一个线程上执行.
When we create an instance of a class, we are creating an object that is residing in JVM's shared memory. Now, these threads are independently executing code that operates on these instances. Each thread has a working memory, in which it keeps data from the main memory that are shared between all threads. This is where the reference to the Singleton object you have created resides. Essentially what is happening is that the bytecode which was generated and is representative of the singleton object you created is being executed on each one of these threads.
现在内部情况如下:
每个 JVM 线程都有一个私有 JVM 堆栈,与线程同时创建.现在,JVM 有一个在所有 JVM 线程之间共享的堆.堆是为所有类实例和数组分配内存的运行时数据区域.堆是在 VM 启动时创建的.当您的线程请求单例实例时,它将指向此单例的字节码所在的堆中的引用.它将执行适当的代码.在您的情况下,它将为第一个请求执行第一个方法,为第二个请求执行第二个方法.它能够这样做是因为没有锁或限制阻止编译器将程序计数器指向堆中分配此实例的区域.Singleton 类对 Java 虚拟机的唯一限制是它在该类的堆中只能有一个实例.就是这样.除此之外,您可以从您的方法中引用它 100 次,编译器将指向相同的字节码并简单地执行它.这就是为什么我们通常希望 Singleton 类是无状态的,因为如果我们有任何线程访问它,我们不希望内部变量因为缺乏并发控制而发生变异.
Each JVM thread has a private JVM stack, created at the same time as the thread. Now, The JVM has a heap that is shared among all JVM threads. The heap is the runtime data area from which memory for all class instances and arrays is allocated. The heap is created on VM start-up. When your thread requests the singleton instance, it is going to point to a reference in the heap where the bytecode for this Singleton resides. It is going to execute the appropriate code. In your case, it is going to execute the first method for the first request and the second method for the second request. It's able to do this because there are no locks or restriction preventing the compiler from pointing the program counter to the area in the heap where this instance is allocated. The only restriction that the Singleton class puts on the Java Virtual Machine is that it can have only one instance in the heap of this class. That's simply it. Other than that, you can refer to it 100x times from your method, the compiler is going to point to the same bytecode and simply execute it. This is why we typically want the Singleton class to be stateless because if we any thread access it, we don't want internal variables to be mutated because of the lack of concurrency control.
如果您有任何问题,请告诉我!
Please let me know if you have any questions!
相关文章