如何为多个 jvm 支持创建单例 java 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12032895/
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
How to create singleton java class for multiple jvm support?
提问by Rahul Agrawal
For example I have DBManager.java Singleton Class, which I have to deploy on clustered environment. It is a web based application, with following deployment stratergy
例如,我有 DBManager.java 单例类,我必须将其部署在集群环境中。它是一个基于 Web 的应用程序,具有以下部署策略
Apache Load Balancer --> Tomcat 6 (3 Servers in cluster).
Apache 负载平衡器 --> Tomcat 6(集群中的 3 个服务器)。
I have to maintain single instance of DBManager for 3 tomcat instances.
我必须为 3 个 tomcat 实例维护单个 DBManager 实例。
My code is
我的代码是
package com.db.util;
public class DBManager {
private static DBManager singleInstance;
private DBManager () {}
public static DBManager getSingleInstance() {
if (singleInstance == null) {
synchronized (DBManager.class) {
if (singleInstance == null) {
singleInstance = new DBManager ();
}
}
}
return singleInstance;
}
}
I have been searching a solution to this problem, and found something like JGroups API. Can this be achieved using JGroups ? Any Idea, How to implement that ?
我一直在寻找这个问题的解决方案,并找到了类似 JGroups API 的东西。这可以使用 JGroups 来实现吗?任何想法,如何实现?
采纳答案by djna
Java gives you a singleton in each instance, you need some kind of coordination between the instances so at any given time one of them is active, but if the active one dies then a different instance becomes active.
Java 在每个实例中为您提供一个单例,您需要在实例之间进行某种协调,以便在任何给定时间它们中的一个是活动的,但是如果活动的一个死亡,则另一个实例变为活动状态。
Some app servers have built in capabilities to control such coordinated worker instances, I don't know whether Tomcat has such a function.
一些应用服务器内置了控制这种协同工作实例的能力,不知道Tomcat是否有这样的功能。
Building such functionality yourself is surprisingly difficult, see this questionand note that that question gives links to a useful library - which to me looks quite complex to use.
自己构建这样的功能非常困难,请参阅此问题并注意该问题提供了指向有用库的链接 - 在我看来使用起来非常复杂。
However in your case you have a database, and that gives you a point of coordination. I haven't designed this in detail, but I reckon it's possible to create a reservation scheme using a dedicated row in a control table. It will be a bit tricky to do this efficiently, balancing the speed of detection of an instance death with the overheads of polling the database to see which instance is active, but it seems doable.
但是,在您的情况下,您有一个数据库,这为您提供了一个协调点。我没有详细设计它,但我认为可以使用控制表中的专用行来创建保留方案。有效地做到这一点会有点棘手,平衡检测实例死亡的速度与轮询数据库以查看哪个实例处于活动状态的开销,但它似乎是可行的。
The idea is that the record contains a "reservedUntil" timestamp and "processId". Each process reads the record, if it contains it's own id and the timestamp has not yet expired it knows it can work. When the time is nearly expired, the active process updates the timestamp using an optimistic locking style "Update where timestamp == old timestamp" to manage race conditions. Each non active process waits until the timestamp it last read has expired and then attempts to to take control by updating the record, again using an optimistic locking Update where. Usually that attempt to take control will fail, but if it succeeds we now have a new active instance, and due to optimistic locking we can only ever get one active instance.
这个想法是记录包含“reservedUntil”时间戳和“processId”。每个进程读取记录,如果它包含自己的 id 并且时间戳尚未过期,则它知道它可以工作。当时间即将到期时,活动进程使用乐观锁定样式“更新时间戳==旧时间戳”来更新时间戳以管理竞争条件。每个非活动进程都等待直到它上次读取的时间戳过期,然后尝试通过更新记录来控制,再次使用乐观锁定 Update where。通常,控制权的尝试会失败,但如果成功,我们现在有一个新的活动实例,并且由于乐观锁定,我们只能获得一个活动实例。
回答by Vikdor
Singleton ensures only one instance of the class in a given JVM.
Singleton 确保在给定的 JVM 中只有该类的一个实例。
What is the issue with multiple DBManagers, one for each JVM, in your case?
在您的情况下,多个 DBManagers 有什么问题,每个 JVM 一个?