Singleton and Context - java

I have started learning android using Android Big Nerd Ranch guide.
Listing 9.1 Setting up the singleton (CrimeLab.java)
public class CrimeLab {
private static CrimeLab sCrimeLab;
private Context mAppContext;
private CrimeLab(Context appContext) {
mAppContext = appContext;
}
public static CrimeLab get(Context c) {
if (sCrimeLab == null) {
sCrimeLab = new CrimeLab(c.getApplicationContext());
}
return sCrimeLab;
}
}
Project- we are creating list of crime objects and we used this class to store the list.
I am having trouble to understand the need of the Singleton class provided in Listing 9.1. Why do we need this class in the first place? and why do wee need a context variable and what does it hold ?
I searched google and found out that context is used to inform what is going on with other parts of the application. However, I didn't quite get what are we informing CrimeLab about? Can we create crimeLab without a singleton class? if Yes, why we used crimeLab as a singleton class?

It's not an issue of Android, it's just a design pattern itself.
I have read this example in the Android Big Nerd Ranch guide. Listing 9.1 Setting up the singleton (CrimeLab.java) and the reason of having it in singleton was described by we want to store the shared data. Let imagine that when we construct the CrimeLab object without singleton in 2 places:
CrimeLab cb1 = new CrimeLab(context);
CrimeLab cb2 = new CrimeLab(context);
it creates the new objects and the stored data in cb1 and cb2 are different.
Let imagine about you are using database in the application, it should be only one? Yes.
But to target the same purpose (single data place), we can use the static methods or properties, but you need to prevent creating object by hiding the constructor
private CrimeLab(Context appContext) {
mAppContext = appContext;
}

A singleton is a class of which there will only ever be at most one instance. Hence the private constructor and the public static get.
The public static get is often parameterless. And the reason is that if it is called with different parameters then the order of the call will cause the singleton to be initialized differently, thus you are prone to race conditions.
Without more context I only can conclude that such code is bad.

Related

What are the tricks to make lazy initialization thread safe and efficiency considering the costs of sychronized keyword?

After reading the lazy initialization of expensive resources in the book around Page 106-108 - functional programming in Java by Venkat Subramaniam, it is found hard to understand the tricks with this code snippet
my understandings:
variable heavy in class Holder is of type Supplier<Heavy>
vs
local class HeavyFactory inside the method createAndCacheHeavy is a sub class extends Supplier
It seems only run once to execute that lambda method and then alter the outer member variable of class Holder.heavy
I am confused about below code the heavy is then later assigned with new reference pointing to the sub class extends Supplier
please if anyone could share hints the tricks here to gain the advantages of author proposed to save performance penalty from synchronized keyword and also taking care of thread safety. It also mentioned virtual proxy pattern. Did I miss out any key info to understand it?
package fpij;
import java.util.function.Supplier;
public class Holder {
//only run once here? before heavy get reassigned to HeavyFactory, the local class to that lambda method?
private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
public Holder() {
System.out.println("Holder created");
}
public Heavy getHeavy() {
//the 2nd time it will call always the HeavyFactory.heavyInstance?
return heavy.get();
}
private synchronized Heavy createAndCacheHeavy() {
//create a local class inside method? Is the real trick/hack here I missed out so it will avoid 2nd time the synchronized penalty?
class HeavyFactory implements Supplier<Heavy> {
private final Heavy heavyInstance = new Heavy();
public Heavy get() { return heavyInstance; }
}
if(!HeavyFactory.class.isInstance(heavy)) {
heavy = new HeavyFactory();
}
return heavy.get();
}
public static void main(final String[] args) {
final Holder holder = new Holder();
System.out.println("deferring heavy creation...");
System.out.println(holder.getHeavy());
System.out.println(holder.getHeavy());
}
}
package fpij;
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
If you are really concerned on the cost of synchronized, there a simple way to make it work correctly while keeping the initialization lazy.
It use the property that the classloader ensure synchronization when the class is loaded. It garentee that no other thread will be able to access the class until it is fully loaded. And the class load is actually lazy: it load the class only when the class is actually used from the first time.
If the only feature of class HeavyFactory is to provide the singleton instance, it will be loaded only when the getInstance is called and all will play nicely.
class HeavyFactory {
private static final Heavy heavyInstance = initInstance();
public static Heavy getHeavyInstance() {
return heavyInstance;
}
private static Heavy initInstance() {
heavyInstance = new HeavyInstance();
[...] // Other init stuff
return heavyInstance;
}
}
Edit: The init of complex objects and wiring of dependencies is so common that frameworks like JEE or Spring have implemented ways to do simplify it.
If you use spring for example, you would be able to just declare a given service as a singleton and then declare a dependency on it where you need it. The init would be done when the spring framework initialize in proper order:
// We instruct spring to create a shared instance of heavy
// with #Component annotation
// The instance would be created eagerly at the start of the app.
#Component
public class Heavy {
public Heavy() { System.out.println("Heavy created"); }
public String toString() { return "quite heavy"; }
}
// For the example another service using the Heavy shared instance
#Component
public class ClientDependingOnHeavy {
// We ask spring to fill it automatically the shared instance for us.
#Autowired
private Heavy heavy;
public String foo() {
//So we can use the instance like any object.
System.out.println(heavy.toString());
}
}
Well spring or JEE are quite complex advanced frameworks. For a single case they would not be worth it at all. For a whole application it would make sense. You'd need quite some reading/tutorials to make the second example work if you don't already know them. But in the long run, it may be worth the effort.

Singleton Use - How to make Data Available to all Classes?

I have created a singleton class using the following code:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
I now want to make data from my program available to all of my classes using this singleton class (any suggested modifications are more than welcome). How do I proceed to do so?
Well now you can initialise your Singleton with data in your constructor, or you can add methods to your Singleton class to get data.
Then you'll just have to import the Singleton class in your other classes and get your instance with getInstance().
If you want to look into a more up to date way of accessing data from multiple classes, you could take a look into dependency injection.

Dependency Injection Java Design Pattern Singleton

I have some serious problems to understand, how to work with Dependency Injection and especially the singleton design pattern in a multithreaded environment.
Lets say i have a class:
public class DependencyOne {
private DependencyTwo dependencyTwo;
private DependencyThree dependencyThree;
private Integer aNumber;
public Foo(Integer aNumber, DependencyTwo dependencyTwo, DependencyThree dependencyThree) {
this.aNumber = aNumber;
this.dependencyTwo = dependencyTwo;
this.dependencyThree = dependencyThree;
}
public doSomething() {
dependencyTwo.doSomethingInDepOne(aNumber, dependencyThree);
}
}
public class DependencyTwo {
private DependencyThree dependencyThree;
private aNumber;
public Foo(Integer aNumber,DependencyThree dependencyThree) {
this.aNumber = aNumber;
this.dependencyThree = dependencyThree;
}
public doSomething() {
dependencyThree.doSomethingInDepOne(aNumber);
}
}
public class Main {
public static void main(String[] args) {
DependencyOne depTwo = new DependencyTwo("foo", "foofooo" .... <- just random config);
DependencyOne depThree = new DependencyThree(1,2,3,4,5,12,3,1235 <- just random config);
DependencyOne depOne = new DependencyOne(123, depTwo, depThree);
depOne.doSomething();
}
}
Now lets imagine, DependencyThree needs to be a singleton for various reasons, e.g. a JPA EntityManagerFactory, Centralized Logging or whatever at a global level, not per thread.
Injector injector = Guice.createInjector(new DependencyThree());
A injector as far as i understand should only be created once.
Now my question, what is the best way to provide access to one instance of the DependencyThree Class.
**
I don't want pass the dependencythree object through all other
classes, to get access of it.
**
At the moment i've just created a global singleton, which returns the instance, when i ask for one.
But some people say, that this is very bad design, (is it?).
How do i use dependency injection, on this setup, or shouldn't i use it at all ? This code is just raped a bit, it usually runs in a multithreaded environment.
Guice provides an #Singleton annotation, but this is per thread and not multihreaded.
How do i implement a global singleton in Guice, which is lazy created ?
#Singleton in Guice means that once an instance of the target class is created, that very same instance is returned for all subsequent injection requests. The injector itself is thread safe and thus can be safely shared among threads.
Now, when does injection happens? Injection happens when you ask Guice to get an instance instead of using the new operator yourself.
You only have to ensure that there are no circular dependencies and that lifetimes of injected objects are clearly defined in such a way that #Singleton instances are created before depending classes and are possibly destryed after. By the way, there's nothing wrong with the singleton concept itself: sometimes you simply have a physical resource that can't be represented by more than on instance. It's the singleton pattern with Java static and lazy loading that it's often criticized because it's somewhat non-trivial to implement and there are safer alternatives (like a dependency injection framework)

Is it safe to store a Dao as a static member on a class?

I'm using OrmLite to handle persistence in an Android application.
The OrmLite documentation discusses DAO Enabled Objects, along with providing a class you can extend to tell OrmLite you want to have the Dao set on instances of the class that are retrieved from the database.
This has some nice properties, like letting object.update() and object.refresh() DTRT.
For non-database-generated objects, there is an object.setDao(Dao) method you can use.
Would it be problematic to instead just initialise a Dao as a static member variable on the class at start?
public class Order extends BaseDaoEnabled<Order, Integer> {
protected static globalDao = null;
public Order() {
// Set non-static dao used by parent BaseDaoEnabled
this.dao = globalDao;
}
In the main class of the program I would initialise globalDao once with a Dao appropriate for the object.
This would have the nice property of allowing us to do database operations given an instance of the class even without access to OrmLiteSqliteOpenHelper.getDao().
I think this is threadsafe, since my reading of DaoManager indicates there is generally only one Dao per class anyway.
[ Sorry for the late response. ]
Would it be problematic to instead just initialise a Dao as a static member variable on the class at start?
Yes and no. You need to make sure when the application closes that the DAO is set to null so it gets reinitialized when it comes back. The problem is that I've see applications that are stopped but the classes are still in memory. Then if the user re-runs the application the static initializers will not be reinstantiated and old versions of the DAO with now dead connections to the database will be in place.
The right thing to do is to mirror the behavior that the DatabaseHelper class uses in the HelloAndroid project. To paraphrase it:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private Dao<SimpleData, Integer> simpleDao = null;
public Dao<SimpleData, Integer> getDao() throws SQLException {
if (simpleDao == null) {
simpleDao = getDao(SimpleData.class);
}
return simpleDao;
}
#Override
public void close() {
super.close();
simpleDao = null;
}

Singleton lazy vs eager instantiation

If a singleton is implemented as follows,
class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
How is this implementation different from the lazy initialization approach?
In this case,the instance will be created when the class is loaded and the class itself is loaded only on the first active use (for example, Singleton.getInstance() not when you declare for instance Singleton singleton = null;)
Even with lazy initialization approach, the instance is created on the call to getInstance()
Am i missing something here?
With lazy initialization you crate instance only when its needed and not when the class is loaded. So you escape the unnecessary object creation. That being said there are other things to consider too.
In lazy initialization you give a public API to get the instance. In multi-threaded environment it poses challenges to avoid unnecessary object creation. you put synchronization blocks which poses unnecessary locking to be done to check for object already created. So it becomes a performance issue in this case.
So if you are sure that creating you object is not going to take any significant memory and its almost always going to be used in your application then its good to create in static initialization. Also please do not forget to make your instance final in this case as it make sures that the object creation is reflected properly and in totality to main memory which is important in multi-threaded environment.
Please refer this tutorial from IBM on Singleton+ Lazy Loading+ Multithreaded Environment case
===============Edit on 09/09/2018====================
You should also look at object creation on demand pattern here.
You may call any other static methods or static member variable too to load the singleton instance.
class Logger {
private static Logger instance = new Logger();
public static String LOG_LINE_SEPERATOR =
System.getProperty("line.separator");
public static Logger getInstance() {
return instance;
}
public static String logPattern() {
return null;
}
}
...
Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
For the reasons you mention, this is just a more complicated way of doing much the same as
enum Singleton {
INSTANCE;
}
Using lazy initialisation is only useful if you are concerned that the class could be initilised but you don't want to load the singleton at that point. For most situations this is over kill.
Note: Just referencing the class does not initialise the class.
e.g. Say you have a badly written class which cannot be initilised until some condition is set. In this case n must be non-zero.
public class Main {
public static void main(String ... args) {
Class c= LazyLoaded.class;
System.out.println(c);
}
static class LazyLoaded {
static int n = 0;
static {
System.out.println("Inverse "+1000/n);
}
}
}
prints
class Main$LazyLoaded
First of all, the singleton pattern is overused. What you really want to do if you want "one of something" is to declare it a singleton in your DI framework of choice. This is effectively a configuration driven eager singleton, and frees up options for injecting mocks to do proper testing.
Why not lazy load? Unless your class has a massive initialization routine in construction (which I would argue is also an anti-pattern), there is no benefit and lots of drawbacks to lazy loading. You're just adding complexity and possibly breaking your program if it's not done correctly. The correct way (if you must) is to use the Initialization-on-demand holder idiom.
For lazy loading singleton instance, I am using as below.
class Singleton {
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if(null==instance){
synchronized(Singleton.class){
if(null==instance){
instance = new Singleton();
}
}
}
return instance;
}
}

Categories

Resources