I have a stateless session bean which needs access to a factory class. Is it best to declare this factory class as a static or instance member in the SLSB? Am I correct in saying that, as SLSBs are reused, only one instance of the factory will be created per bean (when going with the instance member option), as opposed to one instance per request?
SLSB instances are pooled, and hence serve potentially many requests over their lifetime, so as you say instance variables are not recreated for each request.
The "natural" way for SLSB is to have each instance independent, no statics, no need for synchronisation between instances. Hence if it's possible I'd have a factory instance per SLSB instance.
Don't assume that an instance of the SLB will not be created per request. The container is within its rights to create one every request; equally, it is also allowed to have only a single instance (I think). More generally, the container will maintain a pool of them.
If instantiating and/or initialising your SLSB is relatively expensive, you should investigate exactly what your container will do, and if possible configure it explicitly to what you want it to do.
Assuming you do that, then there should be no problem with keeping an instance field in the SLSB class.
Instance variables are not recreated as long as the SLSB is reused from the pool. The lifecycle of SLSB is rather simple: create an instance, use it n times to attend n requests, and eventually throw it away. All these actions are performed by the container. So in the creation process of the bean (controlled by us) we can initialize these instance variables. But never modify the contents of these variables once they are initialised in order to avoid side effects.
You can use static instances if you wish to, but bear in mind that you must handle the synchronization issues by hand; and furthermore, you are constrained to a local factory.
A very elegant solution is provided by EJB 3.1 with the #Singleton EJBs.
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.
Can i use a singleton within a servlet to share information between diffrent session.
I know that only 1 instance Servlet is running at any time. Calling service method for each incoming request. But how about creating another Singleton class (for eg: ShareSingleton) which calls its getInstance() in the servlets Init() method. This ShareSingleton can carry data that needs to be shared between sessions/reqests.
Is it risky to use such an approach in servlets ?
First..see this for the best approach of singletons: http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html
Second: Remember singletons are only single to the JVM. So..if you have more than one JVM running do not expect each singleton to have the same state.
Third: To be safe, I would instantiate the singleton from a listener of the servlet context.
see http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
define a class in your web.xml and instantiate it there. Your singleton will be created when your webapp starts up rather than when n people hit the service method of your servlet at once.
Yes, you can. Note that the servlet container may use multiple instance of the Servlet object, so you'll have to make sure one object is shared amongst all these instances.
For example, you might do:
private static final Cache<String,String> = //cache
And then use the value in the cache if it's available, or otherwise update the cache with a newly calculated value. Note that the object that is shared must be 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.
In a traditional n tier web app with servlets for web layer and ejbs(2.0) for biz layer, what is the rationale behind making the servlet model multi threaded and the ejb model single threaded?
i.e there is only 1 servlet instance for all requests, but for ejbs, for each request, there is a new bean instance assigned from the bean pool.
There is indeed only one instance for a specific Servlet since they are supposed to be stateless. In practice this isn't always the case, but so be it.
There are however multiple instances of Stateless session beans (SLSB), and those are pooled.
By their very definition, stateless session beans are stateless, so on the surface this seems like a paradox. The things is that while stateless session beans are stateless with respect to individual calls being made to them, they in fact very often have state.
This state is in the form of references to other resources. The JPA entity manager, which is not thread-safe, is a prime example here. During a single call to a stateless session bean, the caller must have exclusive access to this resource. When the call returns, the next caller can have exclusive access, etc.
If a single instance was used, then either all callers would have to wait on each other (which is of course killing for performance), or they would have the access this single instance concurrently. In the latter case, the bean implementor has to do manual locking of the non thread-safe resources like the entity manager which is often brittle, error-prone and in the end still causes callers to wait on each other.
So, in order to improve performance and still have the safety guarantee, multiple instances are being used.
Those instances are then being pooled and re-used instead of created fresh for each request, because finding, initializing and injecting all required dependencies of the bean can potentially be time consuming.
All of this thus automatically also means that if you inject an entity manager or other non thread-safe resource into a Servlet (which is allowed), you may run into problems. This is a small loop-hole in the Java EE architecture, which is of course easily worked around by simply making use of stateless session beans.
I think that typically servlets present thin facade to the heavy logic implemented in EJBs. Servlets should be stateless and therefore there is no reason to create more than one instance of the same servlet.
If you are using stateless beans only I think that there is no reason to have more than one instance too. But statefull EJBs have state and therefore you need instance per simultaneous request.
I hope I did not say bullshit.