Ever need to destroy a singleton instance?
Asked Answered
C

8

16

By using a singleton, only one instance of it can be created. Do we ever need to destroy that instance?

I have a singleton DBManager, which manages a JDBC connection and query operations. By calling its static newInstance method, I can get the instance of it, then I do some queries. Finally, I want to close the Database connection, and I call another static method close to close the JDBC connection.

Now the connection has been closed, while the instance of DBManager is still alive but not useful. Do I need to destroy it by for example assigning it to null? Otherwise it may be referenced by mistake later on.

If I assign that instance with null, then call newInstance method again, will I get another new different instance?

Chrome answered 17/3, 2011 at 16:47 Comment(1)
Of course you do once your process ends.Pizarro
W
11

I wouldn't get hung up over the semantics of “singleton”—your requirement is that at most one instance of DBManager exist at any time. Once that instance is rendered useless, you can either destroy it so a fresh instance will be created on demand, or else define your newInstance method (which I might suggest be renamed getInstance) to throw an exception (perhaps IllegalStateException) if it is called after the singleton has been rendered useless.

If you are going to destroy it when rendered useless, I suggest that this be done inside the singleton class automatically, with no outside help. You also should consider completely hiding the singleton DBManager and implementing a delegation pattern instead. This will avoid the problem of a client keeping a reference to the stale DBManager instance. You can then make the delegate object a regular singleton.

Whippoorwill answered 17/3, 2011 at 16:55 Comment(1)
+1 for reminding him to cover the case where it can be recreated.Ammons
O
5

I'd argue that no, you can't destroy a singleton because there needs to be exactly one instance of it available at all times. And arguably it needs to be the same instance, because otherwise it's not really a singleton (e.g. two different classes could hold references to distinct instances of the class).

But incidentally, this is one of the many reasons why I believe the singleton pattern has little to no use in real software. The odds of you wanting exactly one thing, ever, in all circumstances, to the point where you enforce this by preventing people from calling constructors - is just too rigid. This sounds like a situation where at one point it seemed reasonable to have a singleton, but it's now become evident that multiple instances makes sense.

So think about whether this must be a singleton - can you simply make it a wrapper around the connection that's wired in as appropriate?

Optimize answered 17/3, 2011 at 16:50 Comment(4)
It might make sense in this case to have a Singleton for a connection pooling mechanism such as adarshr mentions. You will only ever have one connection pool, and this seems like the right class to handle it. I agree with you on the basic content of your post, and in fact when explaining Singleton to a small-ish group not familiar with design patterns, I ran into many potholes based on all of the cases where Singletons are inappropriate or just plain nonsensical.Judicative
@Judicative Many years ago I worked on an application that use one database. Then we wanted the code to use two databases. The application had singletons. We were completely hosed.Hodgkins
@Tom: That kind of scenario was one of the things we were tripping over. My end conclusion was that I just shouldn't have talked about singletons at all. For me, this question, and Andrzej's answer in particular, really pokes holes in the idea that the singleton is a useful pattern.Judicative
The contract for Singleton says "at most one". Plenty of occasions where a Singleton creation is delayed until it is needed - it's one of the things that makes it (sometimes) better than a static utility class.Ammons
J
2

I think it would be more in keeping with the Singleton pattern to make the DBManager capable of opening and closing the connection without actually destroying the DBManager itself. You would then keep it around until the next time you need a database connection, and ask the same DBManager object to create the new connection. After all, if it's a DBManager, it manages connections; it doesn't represent any individual connection.

Judicative answered 17/3, 2011 at 16:50 Comment(4)
We were probably writing at the same time. I voted you down because you dragged class loaders into it, which will just confuse people.Judicative
Your first comment to mine showed '38 min ago' while this was '34 min ago'. Probably at the same time, yes. ;)Lakeishalakeland
I tend to spend a long time writing answers. I saw Andrzej's answer pop up while I was writing and had to verify that we had different answers.Judicative
+1 That explains perfectly, why you meanwhile commented my answer.Lakeishalakeland
I
2

In such cases, we make use of the Connection Pooling mechanism. Each of your operations which query the database must open and close the connection. However, because we're making use of the Connection Pool, the connection is returned to the pool instead of physically getting closed.

There will be a setting on the pool called IDLE_CONNECTION_TIMEOUT or similar which will automatically expire and close the connections if they're unused for the configured period of time. So, little for the developer to worry about in such cases.

Ireneirenic answered 17/3, 2011 at 16:51 Comment(0)
L
0

Short answer: No.

Longer answer: You cannot destroy a singleton, except you use a special Classloader. If you need to destroy it, you shouldn't use a singleton at all. Maybe you can rewrite it in a way to reopen it - better: avoid the singleton pattern.

Search for anti pattern, or code smell.

Lakeishalakeland answered 17/3, 2011 at 16:55 Comment(4)
-1 It's trivial to build a Singleton that can be destroyed. The programmer decides exactly how far the Singleton pattern will be followed (or not), and class loaders have little to do with it.Judicative
Singleton means, there is just one instance. If you look for the pattern, you will always find a solution which involves static in Java. And then you're stuck. What did the TO say himself about the situation? By calling its static newInstance method, .... If you do something else, and call it still 'singleton', I wouldn't argue with you, but if the TO did have such a thing in mind, he wouldn't have asked the question, would he?Lakeishalakeland
Yes. And newInstance() can easily be implemented to create a new instance and stick it in a static field. At which point it's trivial to write a deleteInstance() method that nulls out the old one (and does other cleanup). This leaves newInstance() in a position to recreate the singleton from scratch. You can fairly argue that this is no longer a singleton, but the class loader is not preventing anyone from doing things this way.Judicative
Well, and it isn't far away from the second solution: allow to open and close the connection, which you successfully adopted.Lakeishalakeland
O
0

Your DBManager class should handle the cleanup if the db connection is closed. i.e if DBManager has a referrence to Connection class , then you can write a code in the newInstance() method to check if connection is alive then return static Reference. something like this:

static DBManager manager;
static DBManager newInstance(){
if (manager == null) manager =new DBManager();
else if ( manager !=null && connection ==null) //if connection is closed 
manager =new DBManager();

return manager;
}
Olvan answered 17/3, 2011 at 17:0 Comment(0)
M
0

The answer should be no you can't destroy a singleton as there should be one and one only. As to your problem, you have a DBManager class, which HASA connection that's closed and become useless.

I'm guessing your aim should be to have one DB connection open at any one time, so I would look at your code here, are you breaking the single responsibility principal and ensure that you split off the Connection responsibility in to a separate class and allow your single the privilege of managing its connections - i.e. closing and reopen it as necessary.

Masquerade answered 17/3, 2011 at 17:2 Comment(1)
There has to be "at most one" Singleton. Creation is often delayed until needed.Ammons
S
-1

Create a getter/setter for the class Variable and set it yo null to re-instantiate an object Ex:

//Singleton support ...
private static A singleton = null;
    public static A get() {
        if (singleton == null){
        singleton = new A();
    }
        return singleton;
}
public static A getSingleton() {
    return singleton;
}
public static void setSingleton(A singleton) {
    A.singleton = singleton;
}

//Re instantiate 
public class Test(){
....
....
    A.setSingleton(null);

}
Semipalmate answered 16/5, 2012 at 19:10 Comment(1)
What is the point of having a setter? Why not just a destroy method (that simply sets the singleton to null, with the advantage that you cannot try to set it to something else)??Skimpy

© 2022 - 2024 — McMap. All rights reserved.