aspose file tools*
The moose likes Beginning Java and the fly likes Related to Singleton class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Related to Singleton class" Watch "Related to Singleton class" New topic
Author

Related to Singleton class

padmaratna kamble
Greenhorn

Joined: Apr 26, 2006
Posts: 26
Can we restrict a class to create only one object? if yes.how?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Moving to Java in General (Beginner).


[Jess in Action][AskingGoodQuestions]
Yuriy Zilbergleyt
Ranch Hand

Joined: Dec 13, 2004
Posts: 429
Isn't the answer in your topic title - the Singleton pattern?

marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Welcome to JavaRanch!

See if this Singleton article (linked to from our Beginners FAQ) helps.


"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Hi, Sachin. Tell us a bit about why you need such a thing. There are some pretty good reasons to have them, and a lot of not so good reasons. There is some chance we might have a different solution to your requirement. Or not.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
Originally posted by Yuriy Zilbergleyt:
Isn't the answer in your topic title - the Singleton pattern?



A little correction:



Because, some one may assign null to theInstance reference and if we will not check it for null and create new instance then it will return null.
pascal betz
Ranch Hand

Joined: Jun 19, 2001
Posts: 547
rathi ji:
why would anyone assign null to "theInstance" ?
if there are chances that someone (this can only be inside static code of the singleton class since its private and static) does this, then better make the reference final so it can not be assigned again. well, make it final anyway.

btw:
your corrected version is not thread safe anymore ! there could be more than one instance of the singleton !

and: there are only a few valid reasons to use the singleton pattern but there are a lot of reasons NOT TO USE SINGLETON. singletons are evil. my top two reasons are: testing (very hard to replace with a mock) and coupling.


pascal
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830

btw:
your corrected version is not thread safe anymore ! there could be more than one instance of the singleton !


Can you explain?
Thanks.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by rathi ji:


Can you explain?
Thanks.


Imagine that theInstance is null (although it actually can't be here, since theInstance is private -- barring reflection tricks.) If two threads call getInstance() at almost the same time, both can see theInstance as being null, both can create a new MySingleton, both can make the assignment, and both can get a different instance of the class as a result!

The only way to fix this, other than initializing the static member when its declared is to synchonize the getInstance() method. There's a fairly obvious trick called "double-checked locking" which lets you synchronize only part of the getInstance() method, but the problem is that for subtle reasons it doesn't actually work -- so don't try to reinvent it
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Note that Yuriy 's original code was just fine. The only thing "wrong" with it is that it didn't use lazy instantiation. Rathi was apparently trying to make a standard singleton with lazy instantiation, but since he initialized theInstance to an instance rather than null, the code didn't really make any sense. Pascal's followup comments seem to miss this point, so by now I'm not really sure what problem is supposedly being worked on.

[EFH]: The only way to fix this...

There is... another. Assuming the goal is a lazily instantiated singleton. (Since Yuriy already gave us a non-lazy one.)


(I'm omitting discussion of what happens to the concept of "singleton" if there are multiple JVMs or multiple classloaders, and whether a singleton is necessary, or even disareable (usually not). See the links already given for plenty of discussion of those topics...)
[ April 27, 2006: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by Jim Yingst:

There is... another.


That's cool, I hadn't thought of using the classloader for non-class-loader-related lazy initialization. I've done this kind of trick for JDK version-testing, but never made this leap. Now I have a new hammer, and I need to go hit something...
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
Thanks EFH, Jim and All for nice explaination.

One question is, where to use early initialization and where to use late initialization??

I guess, if an object is BIG then we should go for early one instead of initializing it at *request time*...

Is it right?

Thanks.
faisal usmani
Ranch Hand

Joined: Jan 14, 2006
Posts: 139

[EFH]: The only way to fix this...
There is... another. Assuming the goal is a lazily instantiated singleton. (Since Yuriy already gave us a non-lazy one.)

code:
--------------------------------------------------------------------------------

public class MySingleton {
private static class Holder
{
final MySingleton instance = new MySingleton();
}
public static MySingleton getInstance()
{ return Holder.instance;
}

}



It might be a little late or may be there is something wrong with by understanding but this code won't compile.

non-static variable instance cannot be referenced from a static context


a solution can be making instance variable static.

regards
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Yep, Jim made a mistake. Nya nya nya!
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
Originally posted by rathi ji:

One question is, where to use early initialization and where to use late initialization??


Your mileage may vary, but I've checked my own code, and all my singleton classes look like this:

-- plenty of instance methods, but just one static method: getInstance

If that's the case, then there's no benefit to using the lazy instantiation, since if your code mentions the singleton class, it's going to call getInstance first.

So the lazy instantiation is only a benefit if your singleton class has other static methods that don't cause instantiation, and the client code calls them without calling getInstance at the same moment.

Which applies to your code?


There is no emoticon for what I am feeling!
R Joshi
Greenhorn

Joined: Feb 21, 2006
Posts: 13
public class Test {
private static Test self = null;

private Test() {
}

public static instance() {
if (self == null) {
synchronized(Test.class) {
if(self == null) { // check again to check if some other thread initialized self
self = new Test(); //lazy instantiation
}
}
}
return self;
}

}


B&S(2.3.1)<br />There are no stupid questions. Answers maybe
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Originally posted by R Joshi:

// check again to check if some other thread initialized self


Yep, that's it -- that's the "double-checked locking" that I previously explained definitely doesn't work in Java versions before 1.5, and arguably still doesn't. Despite published articles and books suggesting that you do this -- don't. Jim's class loader trick above seems like a very nice alternative if you really think that synchronization will have measurable overhead in your application.
[ April 27, 2006: Message edited by: Ernest Friedman-Hill ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[EFH]: Yep, Jim made a mistake. Nya nya nya!

Yep. I notice you didn't catch it though.

I've now edited my original post above to avoid misleading anyone else. Thanks, Faisal, for catching the error.
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
Originally posted by Jeff Albertson:


Your mileage may vary, but I've checked my own code, and all my singleton classes look like this:

-- plenty of instance methods, but just one static method: getInstance

If that's the case, then there's no benefit to using the lazy instantiation, since if your code mentions the singleton class, it's going to call getInstance first.

So the lazy instantiation is only a benefit if your singleton class has other static methods that don't cause instantiation, and the client code calls them without calling getInstance at the same moment.

Which applies to your code?


Didn't get exactly. Sorry.

Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Pugh called that the "lazy-holder" pattern or something akin to it. Though I kind of think in most cases the class isn't likely to be loaded until an instance is needed so murking up code for lazy instantiation is rather silly. In other cases, the holder is perfect.
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Damn, I should have Googled first I wasn't even close in the name. I'm going to quote the entire thing since it's a great explanation of what the OP asked about to begin with and why it's still not good in the new memory model. It's an excerpt from http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html


Does the new memory model fix the "double-checked locking" problem?

The (infamous) double-checked locking idiom (also called the multithreaded singleton pattern) is a trick designed to support lazy initialization while avoiding the overhead of synchronization. In very early JVMs, synchronization was slow, and developers were eager to remove it -- perhaps too eager. The double-checked locking idiom looks like this:



This looks awfully clever -- the synchronization is avoided on the common code path. There's only one problem with it -- it doesn't work. Why not? The most obvious reason is that the writes which initialize instance and the write to the instance field can be reordered by the compiler or the cache, which would have the effect of returning what appears to be a partially constructed Something. The result would be that we read an uninitialized object. There are lots of other reasons why this is wrong, and why algorithmic corrections to it are wrong. There is no way to fix it using the old Java memory model. More in-depth information can be found at Double-checked locking: Clever, but broken and The "Double Checked Locking is broken" declaration

Many people assumed that the use of the volatile keyword would eliminate the problems that arise when trying to use the double-checked-locking pattern. In JVMs prior to 1.5, volatile would not ensure that it worked (your mileage may vary). Under the new memory model, making the instance field volatile will "fix" the problems with double-checked locking, because then there will be a happens-before relationship between the initialization of the Something by the constructing thread and the return of its value by the thread that reads it.

However, for fans of double-checked locking (and we really hope there are none left), the news is still not good. The whole point of double-checked locking was to avoid the performance overhead of synchronization. Not only has brief synchronization gotten a LOT less expensive since the Java 1.0 days, but under the new memory model, the performance cost of using volatile goes up, almost to the level of the cost of synchronization. So there's still no good reason to use double-checked-locking.

Instead, use the Initialization On Demand Holder idiom, which is thread-safe and a lot easier to understand:


Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Joshua Bloch calls it the initialize-on-demand holder class idiom. (Effective Java. p 194.) Close enough either way, I suppose.
[ April 27, 2006: Message edited by: Jim Yingst ]
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Well, he doesn't uses a dash! Like I said, my memory was way off on the name. I just hadn't seen the name mentioned and it's harder to Google without one.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
In case it wasn't clear, I wasn't intending that as a correction or anything - just another bit of info.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Related to Singleton class