简体   繁体   中英

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.

Below is the class which I am using from this github link which I am using currently to make a connection to 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.

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..

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?

// 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..

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
  • 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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