简体   繁体   English

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

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

I am trying to make a class as ThreadSafe Singleton but somehow I am not able to understand how to make ThreadSafe Singleton class which can accepts parameter. 我试图使一个类成为ThreadSafe Singleton但是以某种方式我无法理解如何使ThreadSafe Singleton类可以接受参数。

Below is the class which I am using from this github link which I am using currently to make a connection to Zookeeper - 下面是我正在使用的该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;
    }
}

And this is the way I am calling the above class - 这就是我叫上述班级的方式-

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

Now what I need is if I am calling these two below methods from any class in my program, I should be able to get an instance of it. 现在我需要的是,如果我从程序中的任何类调用下面的这两个方法,则应该可以得到它的一个实例。 So I am thinking to make above class as a Thread Safe Singleton so that I can access these two methods across all my java program. 因此,我正在考虑使上述类成为线程安全单例,以便我可以在我所有的Java程序中访问这两种方法。

isLeader()
getClient()

How do I make above class as ThreadSafe singleton and then make use of isLeader() and getClient() across all my classes to see who is the leader and get the client instance.. 我如何使上述类作为ThreadSafe单例,然后在所有类中都使用isLeader()getClient()来查看谁是领导者并获取客户端实例。

I need to do this only at the initialization time and once it is done, I should be able to use isLeader() and getClient() across all my classes.. Is this possible to do? 我只需要在初始化时执行此操作,一旦完成,就应该可以在所有类中使用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();

This is more of Java question not Zookeeper stuff.. 这更多是Java问题而不是Zookeeper的内容。

A singleton which requires a parameter is a bit of a contradiction in terms. 就参数而言,需要参数的单例有点矛盾。 After all, you'd need to supply the parameter value on every call, and then consider what would happen if the value was different to an earlier one. 毕竟,您需要在每次调用时提供参数值,然后考虑如果该值与先前的值不同会发生什么。

I would encourage you to avoid using the singleton pattern at all here. 我鼓励您在这里完全避免使用单例模式。 Instead, make your class a perfectly normal one - but use dependency injection to provide a reference to a single configured instance to all your classes that need it. 而是使您的类成为完全正常的类-但使用依赖注入为所有需要它的所有类提供对单个配置实例的引用。

That way: 那样:

  • The singleton nature isn't enforced, it's just a natural part of you only needing one reference. 单例性质不被强制执行,它只是您的自然需求,只需要一个引用即可。 If later on you needed two references (eg for different Zookeeper instances for some reason) you can just configure the dependency injection differently 如果以后需要两个引用(例如由于某种原因用于不同的Zookeeper实例),则可以仅配置不同的依赖项注入
  • The lack of global state generally makes things much easier to test. 缺乏全局状态通常使事情更容易测试。 One test might use one configuration; 一种测试可能使用一种配置。 another test might use a different one. 另一项测试可能使用其他测试。 No singleton, no problem. 没有单身,没有问题。 Just pass the relevant reference into the constructor of the class under test. 只需将相关的引用传递到被测类的构造函数中即可。

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

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