java 是否需要销毁单例实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5342357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:42:43  来源:igfitidea点击:

Ever need to destroy a singleton instance?

javasingletoninstancedestroy

提问by chance

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.

我有一个单例 DBManager,它管理 JDBC 连接和查询操作。通过调用它的静态 newInstance 方法,我可以获得它的实例,然后我做一些查询。最后想关闭Database连接,调用另外一个静态方法close关闭JDBC连接。

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.

现在连接已经关闭,而 DBManager 的实例还活着但没有用。我是否需要通过例如将其分配给 null 来销毁它?否则以后可能会被错误引用。

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

如果我为该实例分配空值,然后再次调用 newInstance 方法,我会得到另一个新的不同实例吗?

采纳答案by Ted Hopp

I wouldn't get hung up over the semantics of “singleton”—your requirement is that at most one instance of DBManagerexist 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 newInstancemethod (which I might suggest be renamed getInstance) to throw an exception (perhaps IllegalStateException) if it is called after the singleton has been rendered useless.

我不会纠结于“单例”的语义——您的要求是DBManager在任何时候最多存在一个实例。一旦该实例变得无用,您可以销毁它以便按需创建一个新实例,或者定义您的newInstance方法(我可能建议重命名getInstance)以抛出异常(可能IllegalStateException),如果它在单例之后被调用变得毫无用处。

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 DBManagerand implementing a delegation pattern instead. This will avoid the problem of a client keeping a reference to the stale DBManagerinstance. You can then make the delegate object a regular singleton.

如果你打算在它变得无用时销毁它,我建议这在单例类中自动完成,不需要外部帮助。您还应该考虑完全隐藏单例DBManager并实现委托模式。这将避免客户端保留对陈旧DBManager实例的引用的问题。然后,您可以使委托对象成为常规单例。

回答by Andrzej Doyle

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 mustbe a singleton - can you simply make it a wrapper around the connection that's wired in as appropriate?

所以想一想这是否一定是一个单例——你能简单地把它作为一个适当的连接的包装器吗?

回答by jprete

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.

我认为让 DBManager 能够打开和关闭连接而不实际破坏 DBManager 本身会更符合单例模式。然后将其保留到下一次需要数据库连接时,并请求同一个 DBManager 对象创建新连接。毕竟,如果是DBManager,它会管理连接;它不代表任何单独的连接。

回答by adarshr

In such cases, we make use of the Connection Pooling mechanism. Each of your operations which query the database mustopen 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_TIMEOUTor 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.

调用IDLE_CONNECTION_TIMEOUT或类似的池上会有一个设置,如果它们在配置的时间段内未使用,它将自动过期并关闭连接。因此,在这种情况下,开发人员无需担心。

回答by user unknown

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.

搜索反模式或代码异味。

回答by othman

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:

如果数据库连接关闭,您的 DBManager 类应该处理清理。即如果 DBManager 有对 Connection 类的引用,那么您可以在 newInstance() 方法中编写代码来检查连接是否处于活动状态,然后返回静态引用。像这样:

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;
}

回答by roghughe

The answer should be noyou 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.

答案应该是否定的,你不能销毁一个单身人士,因为应该只有一个。至于您的问题,您有一个 DBManager 类,该类已关闭并变得无用的 HASA 连接。

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.

我猜你的目标应该是在任何时候打开一个数据库连接,所以我会在这里查看你的代码,你是否打破了单一责任主体并确保你将连接责任拆分为一个单独的类和允许您的单身人士拥有管理其连接的特权 - 即根据需要关闭和重新打开它。

回答by Abhi

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

为 Variable 类创建一个 getter/setter 并将其设置为 null 以重新实例化一个对象,例如:

//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);

}