Design patterns - Singleton and class loaders - java

The Head First design patterns book mentions singletons and class loaders.
Question : What about class loaders? I heard there is a chance that
two class loaders could each end up with their own instance of
Singleton.
Answer : Yes, that is true as each class loader defines a namespace.
If you have two or more class loaders, you can load the same class
multiple times (once in each classloader). Now, if that class happens
to be a Singleton, then since we have more than one version of the
class, we also have more than one instance of the Singleton. So, if
you are using multiple classloaders and Singletons, be careful. One
way around this problem is to specify the classloader yourself.
In which situation do Java developers need to have multiple class loaders ? In which situations would multiple class loaders be a problem for singletons ?

Related

Understanding Java singleton Design pattern

During reading the Spring Framework's documentation I came across the following:
Spring’s concept of a singleton bean differs from the Singleton
pattern as defined in the Gang of Four (GoF) patterns book. The GoF
Singleton hard-codes the scope of an object such that one and only one
instance of a particular class is created per ClassLoader. The scope
of the Spring singleton is best described as per container and per
bean.
I don't understand why per ClassLoader? Why don;t per the entire application or in the Context they are considered to be the same things?
Because in the traditional singleton, you have a static variable in the Singleton class to keep the single instance. However since you can load the same class using multiple ClassLoaders, those will have their own static variables and are free to create their own instance.
In most cases this is not a problem anyway.

Will extending a class load up memory?

In the application i'm trying to build, I have a utility class which I'm extending to use the utility methods present within.
#Repository("userdao")
public class UserDAO **extends baseDAO**{
private float PROFILE_FIELD_COUNT=16.0f;
List<UserProfile> ObjList=null;
...
...
...
My question is that will this extension load up all the methods into the memory? Or is it better to instantiate an object for the base class and use the methods through that object? Which is light-weighing in terms of memory consumption?
Extending another class (such that there are two classes) is no different in terms of practical memory usage1 than creating two distinct classes which are both used. Likewise, the "depth" of the extension tree does not affect the memory usage of instances.
The "memory cost" of multiple classes is inconsequential in all but the most limited embedded environments: write the cleanest cost. Independent of the choice of subtyping (it may be better to share "utility methods" through Dependency Injection and Composition), trying to cram everything into a single "DAO class" is likely wrong.
1 There is a difference, see Java Objects Memory Structure and will depend on the particular implementation.

Impact of changes on singleton class loaded by different classloaders

If i have multiple instances of singleton class on different class loaders
and if i have modifications to a reference variable in any of these instances.
E.g if i add/remove an element to Hashmap
Does the change/modification impact the instances on other class loaders as well?
Singleton is per classloader. so changes wont impact other instances loaded using other classloaders.
there are couple of good references:
on Singleton and different classloaders
on Static members and different classloaders
Your "singleton" is one instance per JVM.
Here is a good article discussing classloaders, the relationship between different classloaders to each other, and to the JVM:
http://javapapers.com/core-java/java-class-loader/

Singleton objects and Java servlets

When I access a singleton Java object from withing a servlet, that object is only "single" or "one instance" for the give servlet thread or single throughout the JVM on the Server OS (like Linux)?
I mean when client connects to the servlet/service, are singleton object are unique to each thread created for each client or its unique throughout the whole JVM installed in the machine?
I think the object is unique for each user, not to the whole JVM. The only persistent information is the one you put in the user session.
I'm not sure, but I think you can acomplish to have one instance of a Class in the whole Application Server using the ClassLoader class, however I don know how it's done.
UPDATE:
Taken from the Java Article "When is a Singleton not a Singleton?"
Multiple Singletons Simultaneously Loaded by Different Class Loaders
When two class loaders load a class, you actually have two copies of the class, and each one can have its own Singleton instance. That is particularly relevant in servlets running in certain servlet engines (iPlanet for example), where each servlet by default uses its own class loader. Two different servlets accessing a joint Singleton will, in fact, get two different objects.
Multiple class loaders occur more commonly than you might think. When browsers load classes from the network for use by applets, they use a separate class loader for each server address. Similarly, Jini and RMI systems may use a separate class loader for the different code bases from which they download class files. If your own system uses custom class loaders, all the same issues may arise.
If loaded by different class loaders, two classes with the same name, even the same package name, are treated as distinct -- even if, in fact, they are byte-for-byte the same class. The different class loaders represent different namespaces that distinguish classes (even though the classes' names are the same), so that the two MySingleton classes are in fact distinct. (See "Class Loaders as a Namespace Mechanism" in Resources.) Since two Singleton objects belong to two classes of the same name, it will appear at first glance that there are two Singleton objects of the same class.
I'd say it depends on how the singleton is implemented, but all requests for a given app execute in the same VM, so it should be one instance for all requests.
EDIT: This is assuming a straight-forward Singleton implementation similar to:
public class MySingleton {
private static MySingleton _instance;
// for sake of simplicity, I've left out handling of
// synchronization/multi-threading issues...
public static MySingleton getInstance() {
if (_instance == null) _instance = new MySingleton();
return _instance;
}
}
Yes it is Singleton. But the scope of the singleton depends on where the class is located.
If it is located inside application, it is singleton for that application. If the same class is present inside another application then another object is created for that application and it is singleton for that application.
If it is located outside application and within server, it is singleton for the VM.
According to this
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html
every Web application has it's own class loader, so the singleton will be unique for one application and it can't be visible to another
When you create a Singleton instance, all request instances will share the same instance for the current class loader it uses.
Since all the Servlets run on a webserver which runs on a single JVM, there will be only a single Singelton Object for all your servlets.

sharing an object application wide

It's common to have an object used application wide.
What are the different patterns / models / ways to share an object through an application?
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way? Is creating a static class probably the better and cleaner way? What's your prefered pattern?
It's common to have an object used application wide. What are the different patterns / models / ways to share an object through an application?
One common way is to use the singleton pattern. I would avoid that though.
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way
Absolutely not. Aside from anything else, if it's an instance variable then it wouldn't be "shared" with instances of your other classes anyway. It's also a complete abuse of inheritance which would certainly bite you hard in any application of significant size - your other classes wouldn't logically have an inheritance relationship with your "main" class, would they? As a general rule, inheritance should only be used when it's really appropriate - not to achieve a quick fix.
What's your prefered pattern?
Dependency injection. When your application starts up, create all the appropriate objects which need to know about each other, and tell them (usually in the constructor) about their dependencies. Several different objects can all depend on the same object if that's appropriate. You can use one of the many dependency injection frameworks available to achieve this easily.
Dependency injection generally works better than using singletons because:
The class itself doesn't know whether or not the dependency is actually shared; why should it care?
Global state makes unit testing harder
Each class makes its dependencies clearer when they're declared - it's then easier to navigate around the application and see how the classes relate to each other.
Singletons and global factories are more appropriate when they're for things like logging - but even then, it means it's relatively hard to test the logging aspects of a class. It's a lot simpler to create a dependency which does what you need it to, and pass that to the object under test, than it is to add ways of messing around with a singleton (which usually remains "fixed" after initialization).
If you use a framework like Spring which has dependency injection, you can get all the benefits of "global" objects for free without needing to explicitly define them. You just create a reference to them in your application context and you can inject them into any object you'd like without worrying about issues with synchronizing.
Singleton pattern, AFAIK the preferable way in software engineering.
I believe what you are looking for is the Singleton Pattern. With this pattern you are ensured that only one instance of a class can be created in memory.
Example:
public class mySingletonClass {
private static mySingletonClass singleObject;
// Note that the constructor is private to prevent more than one
//instance of the class
private SingletonObjectDemo() {
// Optional Code
}
public static mySingletonClass getSingletonObject() {
if (singleObject == null) {
singleObject = new mySingletonClass();
}
return singleObject;
}
}
That said, you should try to avoid using it; but there are some acceptable cases, one of which is here.

Categories