ChatGPT解决这个技术问题 Extra ChatGPT

How does the singleton Bean serve the concurrent request?

I have a question regarding how singleton beans serve concurrent requests in detail.

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?

Can anyone explain to me the step-by-step process on how a singleton bean will serve concurrent requests in the JVM and system?

Let me explain with a concrete example. I have a class like Sports:

class Sports {
    public void playFootball() {
    }

    public void 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.

How is it possible with a singleton instance?

No in that link answer is not correct for that question. In that user is asking how the singleton bean serve the concurrent request but he gave answer is how to make a singleton bean as thread safe. Here i am not asking how to make a singleton bean as thread safe. i want to know the logic behind the how the singleton bean is serving concurrent request ?

V
Vineeth Chitteti

Saravan Kumar,

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.

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.

Now the internals.

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.

Now the internals of how this happens is as follows:

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!


Thank you very very much for your explanation. Now i got it clearly and i will let you know if i have any doubt.
Glad to hear Saravan Kumar! :0) Please feel free to reach out if any questions arise!
@Devarsh Desai nice explanation... +1
@157. Do you know anything about GWT. now i have a small requirement in my GWT application. could you see my post on here stackoverflow.com/questions/26654031/…
Well Said @Dev.
V
Varun Phadnis

An ideal singleton bean should not keep any state. That means it will not have any variables that store anything specific to the request it is serving.

Thus, a singleton bean will simply have stateless code (e.g. controller methods) that can be executed concurrently for multiple requests without any concurrency issues.

For example if following was your singleton bean:

@Service
public class Calculator {

   public int sum(int a, int b) {
        return a + b;
   } 

}

In simple terms, when two "requests" invoke sum method of the bean at the same time, that would mean the sum method would be executed concurrently in two different threads. Hence they will have their own execution context which wont overlap with each other. This would safely allow them to run concurrently.

If the same bean was to have state as follows:

@Service
public class Calculator {

   int incrementalMultiplier = 0;

   public int mulitply(int a, int b) {
        incrementalMultiplier++;
        return a * b * incrementalMultiplier;
   } 

}

This could cause issues when serving two requests concurrently because the incrementalMultiplier is the object level state that will be shared by the two requests (threads) and hence could produce unexpected results.

In short a stateless singleton will be able to serve two requests concurrently because they will be in different threads.


Indeed and i want to know how this stateless bean serve the concurrent request ?
Tried to explain it in more details in simple terms... let me know it that helps. :)
Yes threads are having their own stack memory and it will keep the method name and method variable for each thread individually. If the execution context will different for each request, How the same bean will serve the two different context in same time ?
When you think at the level of executing threads, the methods of the bean simply becomes some code to be executed. Why do you think two threads cannot execute the same code concurrently? Since they are in their own context and isolated, it is kind of vaguely analogous to same program being run on two different computers.
Yeah It should execute. I am asking what is the logic behind the screen. How are they doing two different or same work with single bean. Now i got somewhat but sorry still i am not getting clear. Could you explain me elaborately on how the electrical person( singleton bean) will do same work (method) at a time in different place (thread execution context) ?
s
snakedog

I've seen plenty of admonishments to keep shared singleton beans stateless and I wanted to present a use case where a stateful singleton in a web app backing bean makes sense.

I have an administrative web app that, on demand, queries two separate systems (a CRM and a Digital Assets Manager - DAM) for user data, compares the records, and updates the DAM accordingly using its API. This sometimes takes a very long time if there are a lot of updates. The web UI displays the status of the updates in real time, as the browser polls the backing bean using ajax every second to display a progress bar and how many user accounts it has processed. The UI also provides a button to start the sync process and a button to stop it. The sync button is initially enabled and the stop button is not rendered. After the user clicks the start button, the start button is disabled and the stop button rendered enabled.

While the sync is active, I want different clients (different users at the keyboard using the web app in their separate browsers) to see the same state, i.e. the progress bar and number of user accounts processed and the button states. This is important because it makes no sense to kick off a second sync process while one is already in process.


C
Community

To know in details How does the singleton Bean serve the concurrent request? you have to know the following things about Spring Beans

Bean scopes Spring has different bean scopes (e.g. Prototype, Singleton, etc.) but all these scopes enforce is when the bean is created. For example a "prototype" scoped bean will be created each time this bean is "injected". whereas a "singleton" scoped bean will be created once and shared within the application context. "singleton" scoped is default scope of Spring Bean.

Creation of Bean The whole life cycle of Spring Bean is managed by the Spring Container (i.e. ApplicationContext/BeanFacotry) Spring Container internally refers the bean definition (i.e.XML base ot Annotation based) for creating actual instances of the class defined by that bean definition. now when Spring Container get started it refers to the bean definition and instatiate all the defined bean.

Request the Bean. Now when your object make a request to the bean then Spring Container will handover the bean which allready initialized.

Spring Bean Scope

Are Spring objects thread safe?

Spring Tutorial 11 - Understanding Bean Scopes

hope this will help you...


Yes your correct and thanks for your reply but i couldn't see any explanation regarding my question (How does the singleton Bean serve the concurrent request?) in the above answer.
for each request to singleton Bean container will give you the bean which already initialized at starting time of container.
for each request to singleton Bean container will give you the same bean which already initialized at starting time of container and how it will give the same bean at the time of concurrent request ? and how the same bean will do the same work (same method in the class) or different work (different method in same class) in concurrent request ?
T
Tharindu Eranga

This question is 5+ years old by now (2019) and i hope you have found what you are looking for. but i would still post an answer. this may not only cover your question but also described multi-threading behavior in brief.

first of all. the singleton is a design pattern used in programming, which is used to create only one single instance for the entire application (only one for the JVM. as i hope there is only one JVM in your app). multi threading is a processing mechanism. it executes tasks concurrently. i think you are confused because a you've already know that a thread is a logical processing location. and an object is a memory instance. but you did not understand how multi-threading actually works under the hood. as for your question, i will explain this by with spring framework.

so when a user send a request to the server, the server dedicate a separate thread for each request. and in spring, the beans are singleton by default. so the first request begins to execute a method of your singleton bean, and before it is finished, an another request comes and it executes the same method by using another thread.

so what's happening here is that the second thread will not wait the first one to be finished executing the entire method. they executes concurrently, it means the first request will run the first line of the method and then the second thread begins to run the first line. and maybe second line also. Do note that while the first thread executes the first line, the second thread cannot execute the same line and while the second executes the first line and second line, the first cannot execute the second line until the second thread is finished the second line.

even though we call this concurrent execution, it does not execute concurrently at all. (one line is executed by only one thread at same time) according to your question, you are defined two methods in the bean, so they are separate methods. so two threads requesting the two methods at the same time will execute them at the same time. so what i have described will not apply for that scenario and if your beans are created newly for each request then also this will not happen and they execute concurrently.


Your second last paragraph reminds me a movie. Good try though!
@Ram, yeah, it is hard to explain concurrency by using only texts.
@TharinduEranga, I too thought so. To test that - added a Thread.sleep(10*1000) inside a controller method & hit the API 3 times consecutively & checked logs. Summary is, all 3 are getting executed in parallel, thread 2 doesn't wait for Thread-1 to complete sleep to execute it's own wait. Is my testing method wrong or our understanding?
C
Community

Singleton is a bean scope. You have to handle that how to serve for multiple thread access. You can use synchronization or concurrent pakages. Ref: Are Spring singleton beans thread-safe?

For concurrent request, single bean will serve for mutliple requests one by one.


If the singleton bean will serve concurrent request one by one means, Then why we are we going synchronization because the request will get process one by one. Am i correct ?
The concurrent request begin the method invocation "one by one" (even though also this is not completely correct), but the execution may be preemptied, so that a new thread begin the invocation of the same method. Problem is, if the bean is singleton, the same instance is used, and the two execution see the same fields of the singleton; it may happen (and it happens) that you have the first execution set the value of the field, then get preemptied, and start the second invocation. If the second invocation changes the value of those field, the first one then read the changed values.
@Dan M Yeah indeed. but that's is not my doubt. My bean is not having ANY STATE AND declared as FINAL to made it as thread safe bean. My doubt is how the same bean (Singleton bean) and same time will serve the two or more request ?