Singleton --- -where do we synchronize

Discussions

EJB programming & troubleshooting: Singleton --- -where do we synchronize

  1. I just want to make sure i have only one instance per class loader.........Take a look at the performance too....


    private static ServiceLocator me;

    Does this make sense

    // Returns the instance of ServiceLocator class
      public static ServiceLocator getInstance()
      throws ServiceLocatorException {
        if (me == null) {
          synchronized(ServiceLocator.class) {
           if(me == null) {
         me = new ServiceLocator();
    }
    }
        }
        return me;
      }

    or this

    public static synchronized ServiceLocator getInstance()
      throws ServiceLocatorException {
        if (me == null) {
          me = new ServiceLocator();
        }
        return me;
      }

    Threaded Messages (8)

  2. The second option is correct. The first option is incorrect because the conditional statement needs to be synchronized as well.

    Here's an implementation you could also consider...

    static{
      me = new ServiceLocator();
    }

    public static EJBHome getEjbHome( String name){
    }

    in this case, the static intializer created the single instance of the ServiceLocator. Also, you don't need to call ServiceLocator.getInstance()..., just call ServiceLocator.getEjbHome( "com.my.ejb");

    I think you get the point,

    Raffi
  3. Thanks Raffi ..... am basically interested in a lazy loading avoiding the static block.......

    But what is the problem with the first approach .......

    public static ServiceLocator getInstance()
      throws ServiceLocatorException {
          if (me == null) { /// All threads queue up here (A)
           synchronized(ServiceLocator.class) { // one of them moves in (B)
           if(me == null) { //---------- (C)
         me = new ServiceLocator();
    }// End of if
    }//End of synchronization ..... now me is not null(D)
        }
        return me;
      }

    Now after (B) & finishing up with (D) ..when second thread moves in "me" is not null ........ so (C)does not return true for the second thread .... correct me if am wrong....



    Tks & Rgds,
    KK
  4. read "Effective Java"[ Go to top ]

    Read Josh Bloch's "Effective Java"
  5. read "Effective Java"[ Go to top ]

    ... what Sean is referring to is the "double checked locking problem".
    Do a search on this site for "double checked locking" and you will have your answer.
    Short answer is to create the singleton in the static initialisation (as someone else has already said), otherwise you're going to introduce thread contention for the resource (ie a bottleneck).
  6. read "Effective Java"[ Go to top ]

    Thanks........

    basically i feel the "ThreadLocal" could be used in case we use a jvm version 1.4.1 or above with a server vm..

    just for anybody else who wants reference to the code.........and again run a performance test in ur enviroment before u go with this

    private static ServiceLocator me;
    private static ThreadLocal guardAgainstDCL = new ThreadLocal();

    public static ServiceLocator getInstance() throws ServiceLocatorException {
         if (guardAgainstDCL .get() == null) {
           synchronized(ServiceLocator.class) {
             if (me == null) {
               me = new ServiceLocator();
    }//End of inner if
             guardAgainstDCL.set(Boolean.TRUE);
           }//End of synchronized
         }//End of outer if
         return me;
       }

    Thanks,
    KK
  7. I would not use ThreadLocal. That's overkill for a simple problem. Just use the static initializer. It's the simplest solution, does not force callers to invoke the useless getInstance() method, and the chicks dig it too! :-P

    Raffi
  8. A Question of Design?[ Go to top ]

    Static intializer leads to a static method pattern ....

    When everything in a class is static there can only ever be one instance of a class, i.e. all the variables etc. only exist once, resulting in the procedural programming style. Generally holds good for some utility classes.


    Singleton keeps up the concept of OOPs.............and that is the need for the getInstance...... perhaps it still helps with the lazy loading and the performance of ThreadLocal seems to scale well in jdk 1.4.1 & above ......

    Thanks,
    KK
  9. Not entirely true.

    You can still use the static initializer to instantiate the Singleton object and expose the getInstance() method to return the same. You'll see the exact same behavior as the other implementations. This is an age old mechnism tried and tested ;)


    Raj