1

I am completely puzzled by this code because I know the intent is to have thread safe access to a single instance of the object DataService but I don't know if it achieves that.

It just stands out to me Caller class:

protected final DataService dataService = DataService.getInstance();

Singleton class method:

private static DataService dService=null;
public static synchronized DataService getInstance() {
    if (dService == null)
        dService = new DataService();
    return dService;
}

What is achieved by using protected final modifiers in the calling class?

Are they necessary and a good practice?

Abs
  • 3,902
  • 1
  • 31
  • 30

3 Answers3

1

The protected and final modifiers on your first line are not contributing anything to the singleton nature you're referring to.

Protected is just the access modifier, and final determines whether the variable can be reassigned.

What is truly making this a singleton, by the definition of singleton is the fact that you only ever create one dService object (through new DataService()) and since the method is synchronized you are guaranteed that the method will not be called at the same time which could result in two separate objects created erroneously.

  • Will the final modifier ever result in an exception, this bit is what confuses me. If somehow the object is reassigned from null to object ? Is it possible? – Abs Feb 02 '16 at 03:47
  • The `final DataService dataService` object reference will only ever point to what is returned from the `getInstance()` method. Since the that method always checks to make sure the `private dService` object is instantiated before returning the object reference, the answer is no, you cannot get a null pointer back. – Brian Benzinger Feb 02 '16 at 03:51
  • It's also important to note that as of Java 1.5 you can do a much simpler implementation using an enum, but this doesn't suit all situations. See [this other question](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – Brian Benzinger Feb 02 '16 at 12:53
1

As Brian Benzinger said, the protected and final modifiers do not contribute to the thread safety of the singleton class. Protected defines the visibility of the field in the Caller class, i.e. the field can be accessed by other classes in the package. The final modifier indicates that the field must be definitely assigned at instantiation and cannot be reassigned later.

Although there are many ways to implement the singleton pattern in Java, this is the best implementation that I know of:

class Foo {
    private static volatile Bar bar = null;
    public static Bar getBar() {
        if (bar == null) {
            synchronized(Foo.class) {
                if (bar == null)
                    bar = new Bar(); 
            }
        }
        return bar;
    }
}
Austin
  • 8,018
  • 2
  • 31
  • 37
0

So i ended up digging myself.

I found one inefficiency in this way of doing singleton referred to as

Double checked locking.

"In software engineering, double-checked locking (also known as "double-checked locking optimization") is a software design pattern used to reduce the overhead of acquiring a lock by first testing the locking criterion (the "lock hint") without actually acquiring the lock. Only if the locking criterion check indicates that locking is required does the actual locking logic proceed. " " Since synchronizing a method could in some extreme cases decrease performance by a factor of 100 or higher "

The best way as mentioned there for java 1.5+ is usage of the volatile.

class Foo {
    private volatile Helper helper;
    public Helper getHelper() {
        Helper result = helper;
        if (result == null) {
            synchronized(this) {
                result = helper;
                if (result == null) {
                    helper = result = new Helper();
                }
            }
        }
        return result;
    }

    // other functions and members...
}

"the volatile field is only accessed once (due to "return result;" instead of "return helper;"), which can improve the method's overall performance by as much as 25 percent "

Abs
  • 3,902
  • 1
  • 31
  • 30