I am trying to understand the singleton design pattern. It says that only one object is created in the jvm. But I want to understand how does this work in cloud based environment. Also how many objects are created?
A singleton object is created on in the context of a single Java process, running in a single JVM instance. It has nothing to do with whether the process and the JVM runs on a local physical machine, or in a container, or a virtual machine in the cloud.
Also, even on a the same machine, multiple instances of the same process will each produce their own instance of a singleton object. There is nothing magical about the singletons that would cause separate processes to share a singleton instance.
The most typical method for creating singleton objects is to have a static member of a type reference an instance of an object. Since types are only constructed once by the JVM, that implies a single unique reference to the respective object (though there is nothing preventing multiple instances of that object from being created in the general sense).
Going back to your original question - assuming that by "cloud based environment" you meant a distributed application deployed on multiple machines, connected over a network - then again, by default, each machine, running the process would get it's own separate instance of the "singleton", unless there is some other distributed data structure that underlies the "singletons" to make them share state etc.
Incidentally - you didn't ask, but: What is so bad about singletons?
Applying the singleton pattern in the Java world almost automatically means creating singleton objects of a given class. Objects of classes live in the context of the JVM, the "single" instance is per VM process.
It can in fact get worse than that, as multiple class loaders withing a single JVM can lead to multiple "singletons" within the sam JVM (for example, in a JEE application where class loaders are isolated).
But singleton being a pattern, it can in an abstract way be applied to an application or system as a whole. Of course the technology or component type may have to change.
Distributed systems can also have a concept of "singleton component". Ignite cluster singleton services is a good example. This of course redefines the scope of the singleton object, but it's almost nothing new since we've always used single instances of certain types (such as a single database) in a multi-application system anyway.
Related
I was trying to find out if there is any difference when I am calling a service through its local interface / remote interface in performance within the same JVM.
Based on this article:
http://www.onjava.com/pub/a/onjava/2004/11/03/localremote.html?page=last&x-showcontent=text
Local call should be a bit faster especially in cases for Collection of Objects.
Based on my testing I could not find a big difference between the two however maybe I was trying it with small amount of data.
But anyway I would like to know if it has any downfall to call a service through its remote interface when we are in the same JVM because in my project we are generating both local/remote interfaces however there are no real remote calls, the client and the service is within the same JVM and I am thinking about cleaning up the mess and removing the unnecessary generated remote views because people started to use both without reason.
Thanks!
implementation will vary between containers how remote interfaces perform, you cannot rely on it performing similar to local interfaces (though most containers will realize you're actually accessing a 'local' remote interface). There can be differences, like spawning a new thread for the remote call, passing values by reference (you can for example turn this on in jboss for in-vm remote calls), etc
serialization is always slow, it should be avoided whenever possible
basically just don't do it, absolutely no reason to use the remote interfaces unless you plan on splitting your application into multiple EARs
I am learning Spring, and I know that bean will be by default singleton in one application context.But what if we deploy the applications in distributed system? What will be the practical way to achieve singleton since every time a request comes in, it may be routed to a different machines with a different application context?
I have read Singleton in Cluster environment but the answer is about cache.
I guess we can do something like putting the singleton into a central place(like memcached) , and every time we need this bean and serialize and deserialize it from IO, Does this work? But, in my opinion, this will be cost a lot since some object is very "expensive" to transfer.
Thank you!
Either your singleton is stateless: then you just re-create the same thing in each node, with no communication between nodes needed;
or your singleton is stateful: then you need to distribute its state. This is where memcached or any other of a slew of available distributed caches must be applied. You will still be re-creating the singleton itself in each node independently, but you'll make its internal state reside in the distributed cache.
You can set up your web/app server to make sessions "sticky": once a request is routed to a particular server, all requests in that session go to the same server.
The larger question is: why are you designing and implementing a distributed system this way? A singleton for all can't scale. There's no sense in clustering anything if you insist on this path.
A better solution would be stateless, immutable, functional. Create stateless REST services that model your system.
It depends, if you are going to use the Singleton instance just like a service and you won't store any global variable in it, you won't need to make it distributed.
In some cases that you require the distribution and, therefore, use a cache solution; you may try to optimize your implementation to store minimum data to make it distibuted less costly
I have been doing a lot of research online but can't seem to find a definitive answer to my question which is why I turned to the experts on this site.
When developing with java and Tomcat I have a Singleton class that handles my database connection. So the question is when different users connect to my web application, and my server side java code executes does it get its own singleton class?
For example:
User A logs into my site. An instance of my singleton is created.
User B logs into my site, does the same object (singleton) persist between the two executions of the java code? or is each execution for user A and user B get different singletons?
thank you.
A singleton, stored in a static field, is unique per classloader. So all users of your web application on a tomcat instance would be using the same singleton.
A singleton means a single instance per JVM (per classloader, to be precise). Tomcat does not have seperate environment per user. Instead, it has seperate classloader (and hence separate environment) per web application. Hence, no matter how many users are connected the server side is a single environment and this environment has a single instance of your singleton class which is shared by all the classes loaded in that environment.
Is is possible to create a universal Singleton class, which is, at any given time, only one instance is shared across multiple Java processes?
Multiple Java processes don't share the same virtual machine.
So you would end up with one JVM instance hosting the singleton, then one JVM instance per process which access the singleton using Remote Method Invocation as #Little Bobby Tables suggested.
Anyway consider When is a Singleton not a Singleton:
Multiple Singletons in Two or More Virtual Machines
When copies of the Singleton class run in multiple VMs, an instance is created for each machine. That each VM can hold its own Singleton might seem obvious but, in distributed systems such as those using EJBs, Jini, and RMI, it's not so simple. Since intermediate layers can hide the distributed technologies, to tell where an object is really instantiated may be difficult.
For example, only the EJB container decides how and when to create EJB objects or to recycle existing ones. The EJB may exist in a different VM from the code that calls it. Moreover, a single EJB can be instantiated simultaneously in several VMs. For a stateless session bean, multiple calls to what appears, to your code, to be one instance could actually be calls to different instances on different VMs. Even an entity EJB can be saved through a persistence mechanism between calls, so that you have no idea what instance answers your method calls. (The primary key that is part of the entity bean spec is needed precisely because referential identity is of no use in identifying the bean.)
The EJB containers' ability to spread the identity of a single EJB instance across multiple VMs causes confusion if you try to write a Singleton in the context of an EJB. The instance fields of the Singleton will not be globally unique. Because several VMs are involved for what appears to be the same object, several Singleton objects might be brought into existence.
Systems based on distributed technologies such as EJB, RMI, and Jini should avoid Singletons that hold state. Singletons that do not hold state but simply control access to resources are also not appropriate for EJBs, since resource management is the role of the EJB container. However, in other distributed systems, Singleton objects that control resources may be used on the understanding that they are not unique in the distributed system, just in the particular VM.
Yes, but not without external facilities. The simplest way is to use RMI. Other options include CORBA or Web Services - Just google it up.
The Java EE 6 Tutorial says:
To improve performance, you might choose a stateless session bean if it has any of these traits:
The bean’s state has no data for a specific client.
In a single method invocation, the bean performs a generic task for all clients. For example, you might use a stateless session bean to send an email that confirms an online order.
The bean implements a web service.
Singleton session beans are appropriate in the following circumstances:
State needs to be shared across the application.
A single enterprise bean needs to be accessed by multiple threads concurrently.
The application needs an enterprise bean to perform tasks upon application startup and shutdown.
The bean implements a web service.
But what to use if:
no state has to be shared across the application
a single enterprise bean could be accessed by multiple threads concurrently
no tasks on startup or shotdown need to be performed
Say for example I have a login service with the following interface:
public interface LoginService {
boolean authenticate(String user, String password);
}
Should it be annotated with #Singleton or #Stateless? What are the benefits of the one and the other? What if LoginService needs to get injected an EntityManager (which would be used concurrently)?
Addition: I'm thinking about the Java EE counterpart of Spring service beans, which are stateless singletons. If I understand that correctly the Java EE counterpart are #Stateless session beans and #Singleton Beans are used to configure the application at startup or cleanup at shutdown or to hold application wide objects. Is this correct?
I would go for Stateless - the server can generate many instances of the bean and process incoming requests in parallel.
Singleton sounds like a potential bottleneck - the default #Lock value is #Lock(WRITE) but may be changed to #Lock(READ) for the bean or individual methods.
according to the ejb 3.1 spec, page 110, chapter 4.8.5 "Singleton Concurrency":
It is legal to store Java EE objects that do not support concurrent access (e.g. Entity Managers, Stateful Session Bean references) within Singleton bean instance state. However, it is the responsibility of the Bean Developer to ensure such objects are not accessed by more than one thread at a time.
and furthermore, according to the hibernate entitymanager documentation
An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded.
For me, this means, that you should never inject an EntityManager into a singleton EJB. I would use a singleton EJB as a replacement for a stateless EJB only if EVERYTHING I need to implement in this class supports concurrency without the need to do additional locking / synchronization. As you or other programmers might lose this issue sooner or later from your focus, I personally prefer to not use singleton EJBs except for startup-related issues or features that can be implemented as self-contained units - independently of other beans. In that sense, it doesn't seem to be advisable to inject for example Stateless EJBs into Singletons. Doing so raises the question about the point in time, when the container actually performs the injection of the SLSB into the Singleton? According to the EJB 3.1 Spec, chapter 4.8, the dependency injection gets done before the singleton bean instance can be accessed by clients. So the singleton would obviously stick to the same instance of the SLSB, which seems to become a singleton implicitly, but there doesn't seem to be any guarantee for that. At least I couldn't find anything in the specs, so the behavior might be unpredictable or in the best case container-specific, which is not what most people will want.
Thus, I would only inject Singletons into Singletons or Singletons into SLSBs but not vice versa. For the case of an injection of a Singleton into a Singleton, the Spec offers you the opportunity to define the dependencies between the singletons so that the container can initialize them in the correct order (see the ejb 3.1 spec, chapter 4.8.1 concerning the #DependsOn annotation).
#Stateless will allow you to have multiple copies ready for processing within a JVM (as much as memory and pool size allows) where-as #Singleton there's only one copy in a JVM, even if the single one can support multiple concurrent threads running against it.
In terms of performance #Singleton would be better, provided that the resources it uses allow long running access. However, in a distributed environment sometimes bad things occur, e.g. database or network links may fail.
With a #Stateless bean, the access is more short lived. In addition, should there be a failure it will just respawn and try to establish a new connection to the resource. If something happens like that on a singleton, then it's up the the singleton to handle it without requiring an application restart because the #PostConstruct is only called once per JVM.
I would prefer a bit of fault tolerance vs performance for most situations especially on systems I have no control over.
I think Singleton in concurrency usage will not perform worse than SLSB Pool, it might be even better. The only problem is if you want to share something between threads, you need lock it, and that could be a big problem of performance. So in that case, a SLSB Pool perform much better, because it's not 100% singleton, there are more instances, one got locked, the other one comes up. Anyway if the lock is on some resource sharing by all SLSBs, the pool won't help neither.
In short, I think singleton is better than SLSB Pool, you should use it if you can. It's also the default scope for Spring Beans.
I'm not a JavaEE expert, that's just my feeling, please correct me if I'm wrong.
I think you should use Singleton session bean. Because a login service should be a global service and it does not need to store any state for a concrete user or invocation.
If you're sure you're not sharing state between threads, then a Singleton will be fine in which case you should also annotate the class with #ConcurrencyManagement( ConcurrencyManagementType.BEAN ) which will allow multiple threads running at the same time.
you should go for Singleton if you have any resource that is going to remain constant across the application. Like loading some data from some file or reference data which would not change across the application lifecycle. otherwise, go for SLSB. The drawback of SLSB is that multiple objects would be created hence more memory would be occupied.
Imho I would answer like that:
"no state has to be shared across the application" leads me to stateless bean because of the sentence "To improve performance, you might choose a stateless session bean...".
Considering "a single enterprise bean could be accessed by multiple threads concurrently" you would have to use singleton. If I got it right it is not even possible to access a stateless bean's concurrently when properly used.
"no tasks on startup or shotdown need to be performed" would not matter to me. If tasks have to be done to properly setup a bean then they have to be invoked by a #PostActivate method.
I would logically conclude your question what to use to #Singleton since you asked for concurrent access. Of course you will have to manually control snychronisation of accesses on any further resources (which are not EJBs).