I am really sorry to ask such a question, but I need a bit of your help.
As far I understand, if I use servlets all my business logic ( methods of which I call in controllers ) should be Thread-safe.
Does the same count for Spring? Do I need to make thread-safe methods in service layer when I use #Getmapping #PostMapping instead of using servlets directly?
I do appreciate your help a lot!
Thread safety is a different context . Singleton spring beans(default scope) has no relation with thread safety. Spring container only manages life-cycle of objects and guaranteed that only one object in spring container. So, if a Non thread safe object is injected then obviously it is not thread safe. To make it thread safe you have to handle it by coding.
If it is a web-application , Scope - request can achieve thread-safety as for each new request it creates a new object or Scope - prototype will do this.(for each invocation it creates new bean .)
Related
Spring has singleton and prototype.
EJB has singleton and stateless.
I've been working on EJB since quite some time and I was of the opinion that singleton in EJB means multiple users cant access the class at the same time. And hence users will be kept waiting until the resource is free. Hence always used stateless.
Coming to Spring there is no equivalent of EJB stateless. Everything is singleton by default or new if used as prototype. So what happens when multiple users are trying to access the same singleton bean concurrently. Are they kept waiting?
Maybe my Java fundamentals are not clear here.
What happens when multiple users try to access the same java singleton class or same method of the same java singleton class. How does it work internally? By java singleton here, I mean a class with a private constructor.
Is using Singleton and Stateless in EJB one and the same?
I've been working on EJB since quite some time and I was of the opinion that singleton in EJB means multiple users cant access the class at the same time. And hence users will be kept waiting until the resource is free. Hence always used stateless.
Multiple threads can use same singleton bean at same time.
https://docs.oracle.com/cd/E19798-01/821-1841/gipsz/index.html
Coming to Spring there is no equivalent of EJB stateless.
Maybe there's no annotation, but the behavior is the same.
Maybe my Java fundamentals are not clear here. What happens when multiple users try to access the same java singleton class or same method of the same java singleton class. How does it work internally? By java singleton here, I mean a class with a private constructor.
As other users said, a class with a private constructor isn't necessarily a singleton.
My preferred singleton is:
private static final UserType INSTANCE = new UserType();
private UserType(){
}
public static UserType get(){
return INSTANCE;
}
Multiple threads can use java singleton, there's no synchronization after instantiation.
Is using Singleton and Stateless in EJB one and the same?
Absolutely not. Stateless beans have a pool of instances. Singleton beans have only one, as java singleton objects. But about concurrency, yes, both will not block threads.
I assume you are talking about a Web application. When a web application running in a servlet container, each user request creates a separate thread with its own Stack. Therefore, methods of a singleton class can be executed by multiple concurrent threads. This is the beauty of Java Virtual machine. This allows concurrent users to access same code without blocking each other.
So what happens when multiple users are trying to access the same
singleton bean concurrently. Are they kept waiting?
Don't mix up synchronized with Singletons. Of course, multiple threads can access a Spring Bean the same time.
What happens when multiple users try to access the same java
singleton class or same method of the same java singleton class.
Nothing, but if your Singleton class has instance or class variables, the threads will access them concurrently.
I know this question may sound naive, but I have a confusion regarding the scope of bean in web application.
I know that for every request a new thread is spawned by the container similarly in case of a spring web application a new thread is spawned for every request, then why it is suggested to define my controller, service as singleton, shouldn't the scope of these beans be prototype, because each request i.e. thread will have their own instance of controller, service to work with.
Please enlighten me.
That would be a huge amount of overhead. There's no reason why each request needs its own service bean if you make your code properly thread-safe, which usually just means not keeping any per-request state on the bean.
Even though a new thread is created (or re-used depending on the configuration), the controller and service instances are re-used. If the controllers and services are designed well, they can be stateless with respect to the request and immutable, which will make them thread-safe. It would also lead to far less object creations when their state is not going to change after their creation.
https://gottalovedev.wordpress.com/2014/11/23/bean-scope/
Give this a read. I'm sure it would help.
I think this really depends whether you need to store any state in your bean. Usually, I write my singletons so that they contain no state inside of it and are only used to compute business logic. Without state needing to be managed, then it is acceptable to have all threads share that one singleton instance.
I have this new mvc project where all beans are default scoped(no prototype or session).
with single application context.
i want to know
by making all beans to be default scoped are we trying to achieve the whole application to be run in single thread?
if so will that make each httprequest(from multiple or same sessions) to be queued until the previous one completes?How to avoid such scenario any advice or link would be helpful.
I am relatively new to spring and java development.
Because Spring beans are typically stateless, you can safely call them from multiple threads. That's how your application works: there is only one instance of every controller, service, DAO, etc. But your servlet container (through Spring) calls these beans from multiple threads - and it's completely thread safe.
In fact in plain servlets the situation is the same - there is only instance of each servlet and it can be accessed by infinite number of threads. As long as this servlet is stateless or properly synchronized.
Do not confuse Spring with stateless session beans in ejb that are pooled and each client gets its own instance from the pool.1
1 - In fact that's a bit dumb - since the beans are stateless by the definition, there is no point in pooling them and preventing concurrent access...
Singleton means that the there will be only one instance of each bean. Generally, such beans are processing elements that carry no state. The methods called on them are passed the context which contains the inputs to work on. Hence the method calls on such singleton beans are inherently thread-safe.
I have declared a Spring bean, which polls my email server every so and so seconds. If there is mail, it fetches it, and tries to extract any attached files in it. These files are then submitted to an Uploader which stores them safely. The uploader is also declared as a Spring bean. A third bean associates the email's sender with the file's filename and stores that in a DB.
It turned out that when a few people tried to send emails at the same time, a bunch of messy stuff happened. Records in the DB got wrong filenames. Some did not get filenames at all, etc.
I attributed the problem to the fact that beans are scoped to singleton by default. This means that a bunch of threads are probably messing up with one and the same instance at the same time. The question is how to solve this.
If I synchronize all the sensitive methods, then all threads will stack up and wait for each other, which is kind of against the whole idea of multithreading.
On the other hand, scoping the beans to "request" is going to create new instances of each of them, which is not really good either, if we speak about memory consumption, and thread scheduling
I am confused. What should I do?
Singleton-scoped beans should not hold any state - that solves the problem usually. If you only pass data as method parameters, and don't assign it to fields, you will be safe.
I agree with both #Bozho and #stivio answers.
The preferred options are to either pass store no state in a singleton scoped beans, and pass in a context object to the methods, or to use a prototype / request scoped beans that get created for every processing cycle. Synchronization can be usually avoided, by choosing one of these approaches, and you gain much more performance, while avoiding deadlocks. Just make sure you're not modifying any shared state, like static members.
There are pros and cons for each approach:
Singlton beans are act as a service-like class, which some may say are not a good Object-Oriented design.
Passing context to methods in a long chain of methods may make your code messy, if you're not careful.
Prototype beans may hold a lot of memory for longer than you intended, and may cause memory exhaustion. You need to be careful with the life cycle of these beans.
Prototype beans may make your design neater. Make sure you're not reusing beans by multiple threads though.
I tend to go with the service approach in most simple cases. You can also let these singleton beans create a processing object that can hold it's state for the computation. This is a solution that may serve you best for the more complexed scenarios.
Edit:
There are cases when you have a singleton bean depending on prototype scoped bean, and you want a new instance of the prototype bean for each method invocation. Spring supplies several solutions for that:
The first is using Method Injection, as described in the Spring reference documentation. I don't really like this approach, as it forces your class to be abstract.
The second is to use a ServiceLocatorFactoryBean, or your own factory class (which needs to be injected with the dependencies, and invoke a constructor). This approach works really well in most cases, and does not couple you to Spring.
There are cases when you also want the prototype beans to have runtime dependencies. A good friend of mine wrote a good post about this here: http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/.
Otherwise just declare your beans as request, don't worry about the memory consumption, the garbage collection will clear it up, as long there is enough memory it won't be a performance problem too.
Speaking abstractly: if you'e using Spring Integration, then you should build your code in terms of the messages themselves. Eg, all important state should be propagated with the messages. This makes it trivial to scale out by adding more spring Integration instances to handle the load. The only state (really) in Spring Integration is for components like the aggregator, which waits and collects messages that have a correllation. In this case, you can delegate to a backing store like MongoDB to handle the storage of these messages, and that is of course thread safe.
More generally, this is an example of a staged event driven architecture - components must statelessly (N(1) no matter how many messages) handle messages and then forward them on a channel for consumption by another component that does not know about the previous component from which the message came.
If you are encountering thread-safety issues using Spring Integration, you might be doing something a bit differently than intended and it might be worth revisiting your approach...
Singletons should be stateful and thread-safe.
If a singleton is stateless, it's a degenerate case of being stateful, and thread-safe is trivially true. But then what's the point of being singleton? Just create a new one everytime someone requests.
If an instance is stateful and not thread-safe, then it must not be singleton; each thread should exclusively have a different instance.
Using EJB entity beans you can configure the bean so that when a thread has access to an EJB entity bean, no other threads can access the EJB bean. The container will block other threads until the thread with the lock is finished with the bean. Is there a "Spring way" to do this? Or do you have to just use the standard Java concurrency synchronization approaches to handle this?
If you're referring to pre-EJB3 entities, then this model is a bit broken, and probably not one you want to be following. Concurrent access to the same java object instance of a persistent entity should be avoided. Instead, each thread should obtain its own instance of the entity from the container.
The usual approach to controlling concurrent access to entities is to use transactions, and let the database take the strain. Spring+Hibernate/JPA is more than capable of this.