Singleton, Concurrency and Performance

Dear all,

Below is part of the code of my Singleton ServiceLocator:

publicclass ServiceLocator{

private InitialContext ic;

private Map cache;

privatestatic ServiceLocator me;

static{

try{

me =new ServiceLocator();

}catch(ServiceLocatorException se){

System.err.println(se);

se.printStackTrace(System.err);

}

}

private ServiceLocator()throws ServiceLocatorException{

try{

ic =new InitialContext();

cache = Collections.synchronizedMap(new HashMap());

}catch (NamingException ne){

thrownew ServiceLocatorException(ne);

}catch (Exception e){

thrownew ServiceLocatorException(e);

}

}

publicstatic ServiceLocator getInstance(){

return me;

}

public EJBLocalHome getLocalHome(String jndiHomeName)throws ServiceLocatorException{

EJBLocalHome home =null;

try{

if (cache.containsKey(jndiHomeName)){

home = (EJBLocalHome) cache.get(jndiHomeName);

}else{

home = (EJBLocalHome) ic.lookup(jndiHomeName);

cache.put(jndiHomeName, home);

}

}catch (NamingException ne){

thrownew ServiceLocatorException(ne);

}catch (Exception e){

thrownew ServiceLocatorException(e);

}

return home;

}

}

I 've some questions concerning the concept of Singleton:

1. Assume using the code above. If 2 threads access the getInstance method at the same time, is that one of the thread will get the instance and the other thread will get null or queued up and wait?

2. If the answer of question #1 is positive, can we conclude that Singleton will lower the performance of web application which needs high concurrency?

3. Should we create a pool of ServiceLocators instead of making it Singleton?

4. For EJBs looking up EJBs, why we should not use Singleton ServiceLocator?

Thanks in advance.

Jerry.

[4014 byte] By [blueboya] at [2007-10-2 13:26:29]
# 1

> I 've some questions concerning the concept of

> Singleton:

> 1. Assume using the code above. If 2 threads access

> the getInstance method at the same time, is that one

> of the thread will get the instance and the other

> thread will get null or queued up and wait?

If I read correctly your code, your initialize the singleton instance statically (beforehand).

The first thread that invokes getInstance will be somehow "queued up" while the VM loads and initializes the ServiceLocator class (including executing the static block that initializes the singleton instance).

Afterwards, for the lifetime of this VM, all subsequent threads that will invoke getInstance will undergo no penalty, as no synchronization is involved.

Well-known threading issues involving singleton access (search "Double-checked locking") appear only with code that wants to perform "lazy loading" without synchronization.

Performance issues (or supposed performance issues) incurred by synchronization only occur to code that uses synchronized blocks or methods, obviously.

> 2. If the answer of question #1 is positive, can we

> conclude that Singleton will lower the performance of

> web application which needs high concurrency?

First, I woudn't worry too much about it prematurely.

Next, if this singleton happens to be a performance bottleneck, it wouldn't be in the getInstance but merely in your access to the synchronized collection (which, by the way, does not prevent an EJBLOcalHome to be looked up and inserted twice :o)

But I sincerely doubt it could be anything measurable.

So go ahead with a plain simple singleton this way. If you happen to hit a performance problem, profile it and come back with the results.

> 3. Should we create a pool of ServiceLocators instead

> of making it Singleton?

You need to pool objects when their methods use up a lot of serial time.

Here I really think the getLocalHome will be fast enough to not matter compared to everything else (DB access, file access, network latency, your business logic,...).

If if it did, there would be other means (read-write lock) to lower the serial cost.

Moreover, pooling your locator would divide your cache efficiency (hits/hits+misses) by the number of instances...

>

> 4. For EJBs looking up EJBs, why we should not use

> Singleton ServiceLocator?

?

jdupreza at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

1. Assume using the code above. If 2 threads access the getInstance method at the same time, is that one of the thread will get the instance and the other thread will get null or queued up and wait?

Both threads will get the instance.

2. If the answer of question #1 is positive, can we conclude that Singleton will lower the performance of web application which needs high concurrency?

Singletons may introduce scaling bottle-necks, generally. However, I would first check out the thread-safety of InitialContext before worrying about the Singleton.

Where you do have issues is with your cache. It is read-mostly, but also gets written to, especially when the cache is being filled.

What happens when the other server goes down and then restarts? All your handles will be invalid. How will you refresh the cache?

3. Should we create a pool of ServiceLocators instead of making it Singleton?

No.

4. For EJBs looking up EJBs, why we should not use Singleton ServiceLocator?

Seems fine to me.

- Saish

Saisha at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Thanks jduprez and Saish.

I understand much about Singleton now.

Actually, I misunderstood that Singleton class can only have ONE instance and all clients(threads) that invoke its getInstance method will need to wait until the earlier thread finished using that SINGLE instance.

For question #4:

For EJBs looking up EJBs, why we should not use Singleton ServiceLocator?

I ask this because I saw such argument in another post of Java Forums and I really do not understand. Let me quote the argument below:

For web tier clients using a "singleton" per class loader is a common strategy.

For clients that are EJBs, it may not make sense to make a static "singleton" of the servicelocator and instead just use the servicelocator to hold all the look up code and make the code more manageable. Your EJBs can manage the resources themselves as part of their lifecycle and can use the servicelocator to create objects and the EJB can hold those references. The code for an example is at

http://java.sun.com/blueprints/code/jps131/src/com/sun/j2ee/blueprints/servicelocator/ejb/ServiceLocator.java.html

blueboya at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 4
Your Singleton won't replicate on both sides of a cluster. I'm not sure if it needs to, but it's really not a "Singleton" in that case.Why must it be a Singleton? What's the harm in having more than one?Another question is: Why do you think you need EJBs?%
duffymoa at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 5
Advantage of having Singleton ServiceLocator is that you can cache JNDI lookups which take time.
blueboya at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

I would like to ask whether the argument below is correct or not. I really do not understand...

For web tier clients using a "singleton" per class loader is a common strategy.

For clients that are EJBs, it may not make sense to make a static "singleton" of the servicelocator and instead just use the servicelocator to hold all the look up code and make the code more manageable. Your EJBs can manage the resources themselves as part of their lifecycle and can use the servicelocator to create objects and the EJB can hold those references. The code for an example is at

http://java.sun.com/blueprints/code/jps131/src/com/sun/j2ee/blueprints/servicelocator/ejb/ServiceLocator.java.html

blueboya at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

The code as posted is a bit odd. On a high-level, you instantiate a new ServiceLocator whenever you need one, rather than using the Singleton ServiceLocator. Generally, the EJB spec frowns on Singletons.

What confuses me about the code is what on Earth the static 'me' reference is doing. It never appears to be set or accessed in that class. Odd. Might have something to do with a garbage collection trick, but I am at a loss as to why they declared that particular variable.

- Saish

Saisha at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 8
Saish,I agree with you. I also do not understand why sometimes it uses Singleton but somestimes it does not.
blueboya at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 9
Actually, why should we use Singleton?Why not just make all methods & fields of that class (e.g. ServiceLocator) as static?The situation is similiar in that we changed it from instance-shared-access to class-shared-access. Why do we need to instantiate?
blueboya at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

Well, in a lot of cases, there is probably not a difference. However, if each time you call getInstance() (and the method is synchronized), what if the Singleton maintained a counter, say of open or busy connections? The current user would be able to access the Singleton's instance variables very easily. When the next getInstance() is invoked, that caller would see different instance variables, etc.

- Saish

Saisha at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

memory leak, classloader, jdbc, threadlocal, jvm singleton

http://www-128.ibm.com/developerworks/java/library/j-threads3.html

http://www.patrickpeak.com/page/patrick

http://www-128.ibm.com/developerworks/java/library/j-jtp11225/

https://glassfish.dev.java.net/nonav/javaee5/docs/DG/beade.html

http://www.roseindia.net/javacertification/ibm-287/assemble_enterprise.shtml

http://www.szegedi.org/articles/memleak2.html

http://www.theserverside.com/articles/content/J2EEPerformance/Eliminating_memory_leaks.html

http://support.bea.com/application_content/product_portlets/support_patterns/wls/Investigating_Out_of_Memory_Memory_Leak_Pattern.html

mchan0a at 2007-7-13 11:06:54 > top of Java-index,Other Topics,Patterns & OO Design...