Singletons!

Singletons!

Five different implementations of singleton design pattern in Java:

Singleton class with eager initialisation of object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * The object is initialized while the class is being loaded
 * If your singleton class is not using a lot of resources, this is the approach to use
 * No option for exception handling while object creation.
 */
public class SingletonEagerInitialisation {
    private String name;

    @Override
    public String toString() {
        return "SingletonEagerInitialisation [name=" + name + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private static SingletonEagerInitialisation singletonObject = new SingletonEagerInitialisation();

    public static SingletonEagerInitialisation getSingletonObject() {
        return singletonObject;
    }

    private SingletonEagerInitialisation() {
        name = "Potato";
    }

    public static void main(String[] args) {
        SingletonEagerInitialisation obj = SingletonEagerInitialisation.getSingletonObject();
        System.out.println(obj);
        obj.setName("Brown");
        SingletonStaticBlock obj1 = SingletonStaticBlock.getSingletonObject();
        System.out.println(obj1);
    }
}

Singleton class with eager static block initialisation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*Similar to eager initialization but provides option for exception handling in static block 
 */
public class SingletonStaticBlock {
    private static SingletonStaticBlock singletonObject;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "SingletonStaticBlock [name=" + name + "]";
    }

    static {
        try {
            singletonObject = new SingletonStaticBlock();
        } catch (Exception e) {
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
    }

    public static SingletonStaticBlock getSingletonObject() {
        return singletonObject;
    }

    private SingletonStaticBlock() {
        name = "Potato";
    }

    public static void main(String[] args) {
        SingletonStaticBlock obj = SingletonStaticBlock.getSingletonObject();
        System.out.println(obj);
        obj.setName("Brown");
        SingletonStaticBlock obj1 = SingletonStaticBlock.getSingletonObject();
        System.out.println(obj1);
    }
}

Singleton Lazy initialisation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class SingletonLazyInitialization {
    private static SingletonLazyInitialization singletonObj;
    private String name;

    @Override
    public String toString() {
        return "SingletonLazyInitialization [name=" + name + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private SingletonLazyInitialization() {
        name = "Brown";
    }

    public static SingletonLazyInitialization getSingletonObject() {
        if (singletonObj == null)
            return singletonObj = new SingletonLazyInitialization();
        else
            return singletonObj;
    }
    public static void main(String[] args) {
        SingletonLazyInitialization obj = SingletonLazyInitialization.getSingletonObject();
        System.out.println(obj);
        obj.setName("Brown");
        SingletonLazyInitialization obj1 = SingletonLazyInitialization.getSingletonObject();
        System.out.println(obj1);
    }
}

Singleton with thread safety

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class SingletonThreadSafe {
    private static SingletonThreadSafe singletonObj;
    private String name;

    @Override
    public String toString() {
        return "SingletonThreadSafe [name=" + name + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private SingletonThreadSafe() {
        name = "Potato";
    }

    public static synchronized SingletonThreadSafe getSingletonObject() {
        if (singletonObj == null)
            return singletonObj = new SingletonThreadSafe();
        else
            return singletonObj;
    }
    /*
     * Above implementation works fine and provides thread-safety but it reduces
     * the performance because of cost associated with the synchronized method,
     * although we need it only for the first few threads who might create the
     * separate instances. Here, unnecessary synchronization is not required
     * once the instance variable is initialized. To avoid this extra overhead
     * every time, double checked locking principle is used.
     */
}

Singleton as Optimised Thread Safe (Double checked locks)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class SingletonDoubleCheckedLock {
    private static SingletonDoubleCheckedLock singletonObj;
    private String name;

    @Override
    public String toString() {
        return "SingletonDoubleCheckedLock [name=" + name + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private SingletonDoubleCheckedLock() {
        name = "Potato";
    }

    public static SingletonDoubleCheckedLock getSingletonObject() {
        if (singletonObj == null)
            synchronized(SingletonDoubleCheckedLock.class) {
                if (singletonObj == null)
                    return singletonObj = new SingletonDoubleCheckedLock();
            }
        return singletonObj;
    }
}

Comments

Popular posts from this blog

SelfAwarePotato

Converting google/guava ListenableFuture to Java 8 CompletableFuture

A Generic method to convert ResultSetFuture (of Datastax Java driver for Cassandra) to a list of table-row-model(POJO) for any table query