2

我正在尝试创建一个类,ThreadSafe Singleton但不知何故我无法理解如何创建ThreadSafe Singleton可以接受参数的类。

下面是我从这个 github链接中使用的类,我目前正在使用它来连接到 Zookeeper -

public class LeaderLatchExample {

    private CuratorFramework client;
    private String latchPath;
    private String id;
    private LeaderLatch leaderLatch;

    public LeaderLatchExample(String connString, String latchPath, String id) {
        client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
        this.id = id;
        this.latchPath = latchPath;
    }

    public void start() throws Exception {
        client.start();
        client.getZookeeperClient().blockUntilConnectedOrTimedOut();
        leaderLatch = new LeaderLatch(client, latchPath, id);
        leaderLatch.start();
    }

    public boolean isLeader() {
        return leaderLatch.hasLeadership();
    }

    public Participant currentLeader() throws Exception {
        return leaderLatch.getLeader();
    }

    public void close() throws IOException {
        leaderLatch.close();
        client.close();
    }

    public CuratorFramework getClient() {
        return client;
    }

    public String getLatchPath() {
        return latchPath;
    }

    public String getId() {
        return id;
    }

    public LeaderLatch getLeaderLatch() {
        return leaderLatch;
    }
}

这就是我调用上述课程的方式 -

public static void main(String[] args) throws Exception {
        String latchPath = "/latch";
        String connStr = "10.12.136.235:2181";
        LeaderLatchExample node1 = new LeaderLatchExample(connStr, latchPath, "node-1"); // this I will be doing only one time at just the initialization time
        node1.start();

        System.out.println("now node-1 think the leader is " + node1.currentLeader());
}

现在我需要的是,如果我从程序中的任何类调用以下这两个方法,我应该能够获得它的一个实例。所以我想把上面的类作为一个线程安全的单例,这样我就可以在我的所有java程序中访问这两种方法。

isLeader()
getClient()

我如何将上述类设为 ThreadSafe 单例,然后在我的所有类中使用isLeader()getClient()查看谁是领导者并获取客户端实例。

我只需要在初始化时这样做,一旦完成,我应该能够在我的所有类中使用isLeader()和使用getClient()。这可能吗?

// this line I will be doing only one time at just the initialization time
LeaderLatchExample node1 = new LeaderLatchExample(connStr, latchPath, "node-1");
node1.start();

这更多的是 Java 问题而不是 Zookeeper 的东西..

4

1 回答 1

3

需要参数的单例在术语上有点矛盾。毕竟,您需要在每次调用时提供参数值,然后考虑如果该值与之前的值不同会发生什么。

我会鼓励你在这里完全避免使用单例模式。相反,让你的类成为一个完全正常的类——但使用依赖注入来为所有需要它的类提供对单个配置实例的引用。

那样:

  • 单例性质没有被强制执行,它只是你的一个自然部分,只需要一个参考。如果稍后您需要两个引用(例如,出于某种原因,对于不同的 Zookeeper 实例),您可以以不同的方式配置依赖注入
  • 缺少全局状态通常会使事情更容易测试。一项测试可能使用一种配置;另一项测试可能会使用不同的测试。没有单身,没问题。只需将相关引用传递给被测类的构造函数即可。
于 2014-02-13T23:05:06.090 回答