繁体   English   中英

如何使线程安全可以接受参数的单例类?

[英]How to make thread safe singleton class which can accepts parameter?

我试图使一个类成为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的内容。

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

我鼓励您在这里完全避免使用单例模式。 而是使您的类成为完全正常的类-但使用依赖注入为所有需要它的所有类提供对单个配置实例的引用。

那样:

  • 单例性质不被强制执行,它只是您的自然需求,只需要一个引用即可。 如果以后需要两个引用(例如由于某种原因用于不同的Zookeeper实例),则可以仅配置不同的依赖项注入
  • 缺乏全局状态通常使事情更容易测试。 一种测试可能使用一种配置。 另一项测试可能使用其他测试。 没有单身,没有问题。 只需将相关的引用传递到被测类的构造函数中即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM