Hi I got this asked in an interview question paper.
Singleton and Prototype (non-singleton) which is stateful and which is stateless
I am not sure if prototype is stateless ? Is there any problem with the question ?
The question itself is poorly worded. You can have state in both Singletons and Prototypes (instances), as in it is legal code, but you do not need to have state in either cases. Since Spring is mentioned, I will try to answer this in regards to working with Spring.
In terms of Spring bean scope, singleton will cause the ApplicationContext to create a single instance and use that instance everywhere the bean is asked for. prototype will cause the ApplicationContext to create a new instance each time the bean is asked for.
It is ok for both of these to be stateful.
This question looks pretty legal (though poorly worded) if you read "stateless" as "doesn't have conversational state", i.e. a state related to a conversation with a particular client.
In these terms, singleton-scoped beans are usually stateless, because they are used by multiple clients simultaneosly and their states are not client-specific.
On the contrary, prototype-scoped beans are often created in a context of a conversation with a particular client (though request and session scopes may be more appropriate sometimes), so that their states are related to those conversations (because if your bean don't need to keep any conversational state, you can make it a singleton). In this sense prototype beans are stateful.
Prototype beans and Singleton beans can both hold state. However, according to the Spring documentation, "you should use the prototype scope for all beans that are stateful, while the singleton scope should be used for stateless beans."
A better question might be "Is Singleton thread-safe?"
It's perfectly thread-safe if the state it contains is read-only and immutable. You just have to be more careful if it's mutable. If yes, it could be in danger of becoming a bottleneck for your app. Synchronizing that shared, writable state must be done.
singleton is not data object, think about singleton as data wrapper,
point of access methods,
singleton may be destroyed but presented state stored separately and independently and will be presented after singleton recreated
(android sends greetings, destroyed singletons is notorious trap)
stateless beans: beans that are singleton and are initialized only once. The only state they have is a shared state. These beans are created while the ApplicationContext is being initialized. The SAME bean instance will be returned/injected during the lifetime of this ApplicationContext. .
stateful beans: beans that can carry state (instance variables). These are created every time an object is required.
A stateless singleton is pretty much a collection of static methods; it's no different from a static util class, and it doesn't really matter how many instances there are: 0, 1, 2 or infinity.
Therefore singletons are usually stateful.
(This is why it's nonsensical to argue that a singleton implemented in enum has serialization problem automatically taken care of. It the singleton is stateless, the argument is moot; if the singleton is stateful, the argument is broken)
Related
In an article called Root Cause of Singletons writed by Miško Hevery:
Now, there is one kind of Singleton which is OK. That is a singleton where all of the reachable objects are immutable. If all objects are immutable than Singleton has no global state, as everything is constant.
A singleton always has global state, because all of the design patterns of singleton expose a global reference to the single instance.
But why immutable singleton has no global state?
Since immutable object cannot be reused and are just a use and throw object, improper usage may lead to large amount of garbage, thereby lowering the performance of application.
Singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
A singleton must be thread-safe if used in multiple threads;
immutable objects is also thread-safe but they are inherently thread-safe.
Think of this kind of Singleton that the author describes as just a static, constant object.
The singleton pattern does not necessarily guarantee immutability. So imagine that you have a Singleton that is used by many other modules/components/objects in your code and its state changes. This could arguably lead to unexpected behavior. Object A leaves the singleton in a state A, but nothing guarantees that the singleton's state won't become B after a while.
I think this is what the author tries to outline here. Example singletons of this kind are configuration objects, or static Maps.
J. Bloch in his Effective Java suggests we use an enum-based singleton implementation. For instance:
public enum Application {
INSTANCE;
//methods, fields
}
This implementation is nice in the case of serialization because enums provide us with the capability of serialization by default (and we don't have to be afraid of getting two different instances while deserializing the object).
My question is how this implementation respects multhreading. How to make it thread-safe? What would we probably get if we try to access it from different threads?
The actual enum behavior of instatiating the instance doesn't have an issue with thread safety. However, you will need to make sure that the instance state itself is thread-safe.
The interactions with the fields and methods of Application are the risk--using either careful synchronization and locking, or purely concurrent data and careful verification that other inconsistencies can't happen, will be your best bet here.
Singleton ensures you only have one instance of a class per class loader.
You only have to take care about concurrency if your singleton has a mutable state. I mean if singleton persist some kind of mutable data.
In this case you should use some kind of synchronization-locking mechanishm to prevent concurrent modification of the state and/or use thread-safe data structures.
Please help me understand #Stateless EJB 3 beans.
If I have a bean with two methods and pool size 1, could two clients have simultaneous access to this bean provided that they call different methods on it.
I feel that answer is "no" since ejb does not check whether methods are not linked internally. Is it correct?
The answer is no because the spec guarantees that a given EJB instance is never called concurrently.
in my Seam webapp there is a service returning generators for document generation. These objects are without state (no fields), just methods. Is there anything wrong if there is only one instance of each generator inside the service and each request will return the same instance? Or should I always create and return a new instance?
As long as you're sure there's no state being preserved, I don't see a reason why you'd need to re-create it every time.
It'd be similar behavior to a singleton-scoped bean in Spring
Don't know about Seam but it is something like an EJB underneath, isnt' it? In the EJB world there were stateless ejbs for exactly this case: (re)using objects without state.
So if that's possible with Seam and if those objects don't have state, make them kind of stateless beans. They can be then reused safely.
Re: static methods - that might work but depending on the design used at times you can't have static methods but need object instances, like where you want a certain creation flexibility by using factories.
If the objects have absolutely no state then there is no problem with reusing them. However if they have absolutely no state why not make all the methods static and never create one at all?
EDIT:If this class is a means to pass functionality into a method, then I agree using static methods will not work. In that case then, all else being equal, I would recommend creating a new object purely to indicate to any readers that nothing is preserved between uses. However this is a weak preference, and if there is any other reason to reuse objects, go for it.
I'm trying to create a cache in a webservice. For this I've created a new Stateless Bean to provide this cache to other Stateless beans. This cache is simply a static ConcurrentMap where MyObject is a POJO.
The problem is that it seems as there are different cache objects. One for the client beans, and another locally.
-CacheService
-CacheServiceBean
-getMyObject()
-insertMyObject(MyObject)
-size()
-SomeOtherBean
cache = jndiLookup(CacheService)
cache.insertMyObject(x)
cache.size() -> 1
After this assignment, if I call cache.size from inside the CacheServiceBean, I get 0.
Is it even possible to share static singletons through beans? Finally I decided to use a database table, but I'm still thinking about this.
Thanks for your responses.
As far as I remember you cant be certain that the stateless bean is global enough for you to keep data in static fields. There exist several caching frameworks that would help you with this. Maybe memcache?
EDIT:
http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html#static_fields says:
Nonfinal static class fields are
disallowed in EJBs because such fields
make an enterprise bean difficult or
impossible to distribute
On the surface, this seems like a contradiction in terms, as a cache is almost certainly something I would not consider stateless, at least in the general sense.
#Stateless
public class CacheSessionBean implements CacheSessionLocal {
private static Map<String, Object> cacheMap = new HashMap<String, Object>();
public Object getCache(String key) {
return cacheMap.get(key);
}
public void putCache(String key, Object o) {
cacheMap.put(key, o);
}
}
The caveats regarding distribution of EJBs in a cluster apply to static variables. However, if you're not clustering, they pretty much don't apply to you, so statics are "okey dokey" at this level.
You WILL have synchronization issues.
One way to mitigate that is to configure your container to only create and pool a single instance of the CacheSession bean, then the container will manage that synchronization for you.
You could also manage the synchronization yourself, but you shouldn't do that at the EJB method level, rather you would likely be better having a synchronized Cache object (vs, say, a generic HashMap).
But the key take away is at this point, static variables are simply static variables.
In theory, you will need to be cognizant of the container lifecycle for your Session Bean (as it can potentially release all instances and thereby the actual bean class could be eligible for GC, thus potentially losing any static data). However, in practice, if the service is popular this is unlikely to happen. But, FYI it COULD happen.
When using stateless beans, you have no control of how many instances of them you have (that's up to your app server to take care of). You could have gotten the output from another bean than the one you looked up from your client. Did you print that in your log? In that case, you maybe should've seen more than one output. The point is that you can't know which instance you get when you look up a stateless bean via jndi (you just get one).
And, you don't have state, so I don't know if this is the best choice for a cache.
By static singleton i suppose you mean a singleton object?
Yes, it shouldn't be a problem to access a singleton through many beans. But remember the concurrency problems you'll probably get. The app server (beans in general) abstracts a lot from you.
I know this post was a while ago but there appears to be a new Singleton Bean that will meet the needs of a cache the original question was aiming at:
http://download.oracle.com/javaee/6/tutorial/doc/gipjg.html
Singleton session beans offer similar functionality to stateless session beans but differ from them in that there is only one singleton session bean per application, as opposed to a pool of stateless session beans, any of which may respond to a client request. Like stateless session beans, singleton session beans can implement web service endpoints.
I've tried creating one and referencing it wo issues from a WebService/Stateless bean. worked as advertised.