aspose file tools*
The moose likes Beginning Java and the fly likes Singleton patterns have gotten me confused Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Singleton patterns have gotten me confused" Watch "Singleton patterns have gotten me confused" New topic
Author

Singleton patterns have gotten me confused

Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
I have to start a server for which there can be only one instance and then send it commands and receive data. My naive implementation modified as a result of trying to get my head around this-



which has the advantage, I understand what will happen when it runs, but it was suggested I try and convert that to a singleton pattern. Which if nothing else has got me questioning whether I know anything about Java.



so then in my main code I'd do this???-



As compared with what I thought would happen with my original idea




Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18650
    
    8

Jon Swanson wrote:I have to start a server for which there can be only one instance...


In other words you can only run one copy of the JVM? In that case all of that code is pointless, since its purpose is to make sure there's only one instance of some class inside a particular JVM.

So get rid of all of that stuff entirely and don't bother with the Singleton pattern. You have been completely misled.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I admit, I'm confused by your question too.

When you say "start a server", do you mean 1) An actual process, as Paul inferred? Or 2) A "Server" class within your JVM?

If #1, then the usual approach is to try to open a ServerSocket on some fixed port that you decide on, and keep it open for the life of your server app. If you are able to open it, then no other instance of your server app is running. If you cannot open it, then some other instance is running (or some other process "stole" that port).

If #2, then the usual pattern for a Java Singleton is:



I don't know what the start() and stop() business is. That really has nothing to do with Singletons though.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Jon Swanson wrote:which has the advantage, I understand what will happen when it runs, but it was suggested I try and convert that to a singleton pattern. Which if nothing else has got me questioning whether I know anything about Java.

I suspect you're overthinking it; just think of it an an object that there can only be one of. You use it a bit like you might a Random number generator (except that java.util.Random isn't a singleton).
You set up an instance (which is usually done - by convention - with an instanceOf() method), viz:
RMethods rm = RMethods.instanceOf();
and then you use it, just like you would any other object:
double foo = rm.someRMethod(args);

The only difference is that every instance returned by instanceOf() is the same instance.

The advantage of it in your case is that if, at some future point, you may be able to have more than one instance of the server, you simply change the class to allow more than one instance. With a completely static class, you can't make that change.

However, I'm not convinced that your case necessarily warrants a singleton. At the moment it appears to be just a wrapper to an REngine (whatever that is), so I suspect a factory might do just as well.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:
The advantage of it in your case is that if, at some future point, you may be able to have more than one instance of the server, you simply change the class to allow more than one instance. With a completely static class, you can't make that change.


In general, a bigger advantage, IMHO, is that you can use polymorphism. You can't implement an interface with static methods.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Jeff Verdegan wrote:In general, a bigger advantage, IMHO, is that you can use polymorphism. You can't implement an interface with static methods.

Très true.

This case seems a bit like a JDBC driver actually (as I now recall from Jon's previous post, this REngine is a server for a program called 'R').
Indeed I may have been one of the ones that steered him towards a singleton by suggesting he look at the pattern - the problem being that if the instance isn't managed in some way, every method written on it has to check whether the "engine" is active or not, rather than simply doing it's job and having the engine itself throw an exception if it's invoked illegally (ie, if it's not active).

Winston
Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
Sorry about the confusion. I have a calculation engine R. I need to start it in my Java program. It can only be started once. So once I start it, the program should not be able to call the startR method again. It will be used in multiple classes. So the idea that I could get it started on the first invocation of the method sounds attractive. I thought I would let the RMethods class throw any R engine exceptions and catch them in the code that implements the GUI. That way I can post a message "The R engine has had a brain fart. Save your work and try restarting the program." My feeling is that if the R engine crashes, the state of the program will be confused enough that it will be better to just quit and restart. I think, by catching the exception at the right point, I won't need to check all over the place for the Rengine object being instantiated. Just so that on the first call to an R method, the REngine is started.

So I thought I wanted the constructor to basically start the engine and then everyone would use it, but I am a bit unclear on implementing that as a singleton pattern. I've seen lots of examples, but the code was so abstract that it confused me, so I tried to make an example based on what I want to do.
Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
The reason I did not want to do

RMethods rm = RMethods.instanceOf();
and then you use it, just like you would any other object:
double foo = rm.someRMethod(args);

is because I'll be using the methods in several classes and I didn't want to be passing the instance I create to all the classes. R is just like Math, just statistics. I wouldn't want to make an instance of Math and then try to pass that to any class that used math operations. So I am sure I want to use static methods. So I want to say

double foo = RMethods.someRMethod(args);

and the first call to an RMethod should start the R engine. So I believe I would start it in the constructor method? Just not sure about some of the other bits I tried to copy and paste out of the singleton pattern examples.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Jon Swanson wrote:Sorry about the confusion. I have a calculation engine R. I need to start it in my Java program. It can only be started once.


So, this isn't about only one instance of something existing. It's about only start()ing it once. In that case, just have a member variable that indicates whether it's been started, and have the start() method simply log and return (or throw an exception, depending on your requirements).
Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
I believe that was what I was doing in my original code snippet. Since I am implementing basically advanced Math functions, my thought was to start the R engine in main and any class that used an R method would assume the R engine had been started. It was pointed out to me that if I was clever, I could have the R engine started the first time an R method was invoked. Then I would not have to worry about starting the R engine outside the class that implements the R methods and if I did not use any R methods, I wouldn't have the overhead of the R engine running. It was suggested that I look into singleton patterns. But what I have seen seems to be for the case where you instantiate the method, but every instance points to the same R engine. So I could have each class that uses R methods safely create an instance of RMethods (i.e. additional R engines would not start) and then call methods of that instance. It still makes sense to me that I use static methods: RMethods.someRMethod() not re = RMethods(); re.someRMethod() for the same reason Math.sqrt(x) makes sense rather than math = Math(); math.sqrt(x). I don't see how to convert the singleton pattern examples I found to work for a class of static methods.

PS I am more likely to write my own someRMethod which does not require the server, than need to worry about starting multiple R engines.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18650
    
    8

Jon Swanson wrote:It was pointed out to me that if I was clever, I could have the R engine started the first time an R method was invoked. Then I would not have to worry about starting the R engine outside the class that implements the R methods and if I did not use any R methods, I wouldn't have the overhead of the R engine running.


That's pretty specious. The purpose of this code is to do things with R, isn't it? So at some point pretty early in the process you're going to want to use the R engine. So it seems to me that the simplest and most straightforward thing would be to create an R engine, start it running, and then start using it.

Also that statement implies that this "overhead" is going to be some kind of a problem. I suggest that you have no idea how much "overhead" is involved in running an R engine or what effect it might have on your code -- am I right? There's no point in doing elaborate workarounds to avoid "overhead" unless you have a good reason for avoiding that overhead.

So my suggestion is to keep it simple. Don't waste any more time on this singleton idea. Especially since it's just premature optimization which is causing you to consider itl.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Jon Swanson wrote:It was pointed out to me that if I was clever, I could have the R engine started the first time an R method was invoked. Then I would not have to worry about starting the R engine outside the class that implements the R methods and if I did not use any R methods, I wouldn't have the overhead of the R engine running. It was suggested that I look into singleton patterns.


It sounds like you're talking about lazy instantiation of singletons and/or lazily starting your R Engine. To be blunt, that's bullcrap. I'll only address the lazy singleton instantiation. Similar principles apply to starting the R Engine (by an explicit call to start()), but things are even more under your direct control there, so it's even less of an issue.

In short, there is never a good reason to lazily instantiate a singleton. That is, this kind of nonsense is pointless:


Just do this:


The argument goes like this: "Creating an S is expensive. I don't want to do it unnecessarily." That's nonsense, and here's why:

If you need to use the thing, you'll have to pay the cost of creating it. So the argument only holds if either 1) You might not end up using it in certain runs of your application (so why slow down the overall performance creating something you don't use, or 2) You don't use it until later in your app, and you don't want the early stuff to be delayed by the creation. Those are both really the same thing, and they both don't apply.

Because Java does not load and initialize a class (meaning in this case it won't execute the static declaration/initialization/creation line) until you reference the class. In other words, that cost won't be incurred until you call getInstance() anyway. So if you don't want to incur the cost until you actually use the class, don't call getInstance() until you're ready to use it.

Now, there are two caveats to my rant:

1) If you have static methods in that class that don't depend on the instance, and you use them but don't want to incur the cost of creating the instance, then, yes, with the eager instantiation I recommend, you will incur that cost even though you don't need its results. However, if you're doing this, your class is designed wrong anyway, and those static methods don't belong in that singleton class, so simply refactor them out and this issue goes away.

2) The JVM is not required to wait until a class is referenced in the code to load and initialize it. That's not actually part of the spec. But that's how every major standard JVM has done it for the last 10-15 years. If you're dealing with some specialized niche JVM implementation, this might not hold, and you might end up loading the class at start up time, and never using it or not using it until much later. This is an extreme corner case, however, and if it applies to you, you darn well better know enough of the details to make an informed decision about this and other unusual issues.

And remember, this is a one-time cost, that in the vast majority of cases involves no more than a simple object constructor--microseconds or less. It's only even worth thinking about any of these points if it is so unusually, extremely expensive to create your singleton that it will severely impact your app if it happens unnecessarily or earlier than is required.

I've never seen anything that comes even remotely close to warranting lazy instantiation in 13 years of Java development.

Finally, to touch briefly on the other, related facet, the start() method. Separately from actually creating the thing, if you want to not call start() until it's actually needed, the same overall caveats apply. Namely, it only matters if it's really expensive. In that case, you can have each method check a "started" variable, and call start() if it's not yet set. Otherwise, just start it in the constructor, or, better yet, have some higher level controller call start() before any class is allowed to use it.

In the end, after all my windy blathering, the result is that there's very rarely any point in worrying about lazy insantiation/initialization, and if and when there is, you should know it, not just "hear" it from somebody who thinks he knows what he's talking about.

</rant>


 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Singleton patterns have gotten me confused