• Post Reply Bookmark Topic Watch Topic
  • New Topic

Too much Synchronization?  RSS feed

 
John Williamer
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just a quick (or maybe not so quick question). On a recent bout of refactoring I came across a bunch of static initializers that would initialize some data and throw exceptions.
This was refactored to use lazy loading and data was now initialized in the constructor.

My question is what is the best way to synchronize the whole process of inisitalizing the instance of the class and make it as thread safe as possible.

What I came up with is:
Note: the syncObj is a static object used only to sync.



These are my reasons for the above code:

On line 2 it is more sensible to return the instance straight away without having to enter a synchronize block.

The synchronized block then checks if the instance is null just in-case two threads get to the label marked (a) at the same time (when c_instance is null).

I full accept that the chances of both threads hitting point (a) at the same time is negligible(or even impossible due to the fact that there is not actual code on line 3) but is this good practice?

So what do you guys think?
 
Henry Wong
author
Sheriff
Posts: 22861
119
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The pattern that you just described is called "double checked locking". There are ridiculous amount of volumes about it. Just google for the above term.

Quick summary takeaways (from those volumes)...

- It doesn't really work. (what exactly doesn't work is debateable, IMO)
- It has apparently been fixed in Java 1.5.

Henry
 
John Williamer
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the quick reply. I've read about DCL and it looks like I've got only two options (not including the ThreadLocal method).

Either sync the whole method or put the creation of the instance with the declaration.

The one problem I have found with sync-ing the whole method is that performance is hit (almost 3 times slower than a non synced method).

The other method of using private static final MyClass instance= new MyClass()
is error handling. Something about a classnotfound(static initializer) exception makes me un-easy.
I'd rather have the option to handle exceptions rather than throw a Runtime due to the way my object is created.

I guess I'm just wondering how people who need to lazy load get around the DCL problem without loosing performance and keeping their exception handling strategy?
 
Andreas Schaefer
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another fact is also that Singletons are used way too often. Be aware that a Singleton is defined based on a Class and a Class is defined by its fully qualifed name as well as its ClassLoader meaning that your Singleton must not be a Single instance per JVM but only per Class Loader.

-Andy
 
Henry Wong
author
Sheriff
Posts: 22861
119
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I guess I'm just wondering how people who need to lazy load get around the DCL problem without loosing performance and keeping their exception handling strategy?


I am pretty sure many people will disagree with me on this... so I am qualifying this as... this is my opinion only....

IMHO, I don't see synchronization as a problem. I can't envision this singleton factory method being call so many times to have any effect, much less a major effect. I think it may be better to profile your application, and when you do, I doubt that synchronization will be the problem in many cases.

Henry
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Williamer:
I guess I'm just wondering how people who need to lazy load get around the DCL problem without loosing performance and keeping their exception handling strategy?
I agree with Henry. The answer to this question is, they DO lose performance. But we're talking microseconds per call. This would only be a performance issue if your singleton is accessed extremely frequently; and if it is an issue, then people are going to start cacheing it instead of calling getInstance() several times in a single method. Which brings up another whole set of questions...
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Andreas Schaefer:
Another fact is also that Singletons are used way too often.


This can't be said often enough (even if it's off topic to this forum). It typically leads to too much coupling in the system, which is why I often prefer the Just Create One pattern.
 
John Williamer
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wouldn't caching the instance also lead to synchronization problems due to the fact that the cache will have to check for the existence of the object and if it doesn't exist then call the getInstance?
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Williamer:
Wouldn't caching the instance also lead to synchronization problems due to the fact that the cache will have to check for the existence of the object and if it doesn't exist then call the getInstance?


I think Paul was referring to replacing



by

 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!