2014-02-13 3 views
2

Я пытаюсь сделать класс как ThreadSafe Singleton, но почему-то я не могу понять, как сделать класс ThreadSafe Singleton, который может принимать параметр.Как сделать потокобезопасный одноэлементный класс, который может принимать параметр?

Ниже класс, который я использую из этого GitHub link, который я использую в настоящее время, чтобы сделать подключение к 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()); 
} 

Теперь мне нужно, если я вызываю эти два метода ниже из любого класса в моей программе, я должен иметь возможность получить его экземпляр. Поэтому я собираюсь сделать выше класс как Thread Safe Singleton, чтобы я мог получить доступ к этим двум методам во всей моей java-программе.

isLeader() 
getClient() 

Как сделать выше класс, как поточно-одноплодной, а затем использовать 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 материала ..

+0

Есть ли что-нибудь, что вам нужно, помимо шаблонов, перечисленных на http://stackoverflow.com/q/7048198/2636001? – dst

ответ

3

одноплодный, который требует параметра немного противоречия в терминах. В конце концов, вам нужно будет указать значение параметра для каждого вызова, а затем подумайте, что произойдет, если значение будет отличаться от предыдущего.

Я бы посоветовал вам избегать использования одноэлементного шаблона здесь. Вместо этого сделайте свой класс совершенно нормальным, но используйте инъекцию зависимости, чтобы предоставить ссылку на один сконфигурированный экземпляр всем вашим классам, которые в ней нуждаются.

Таким образом:

  • Одноэлементная природа не соблюдаются, это просто естественная часть вас только нуждаясь одна ссылки. Если по какой-то причине вам понадобилось две ссылки (например, для разных экземпляров Zookeeper по какой-либо причине), вы можете просто сконфигурировать инъекцию зависимостей по-разному.
  • Отсутствие глобального состояния обычно значительно упрощает тестирование. Один тест может использовать одну конфигурацию; другой тест может использовать другой. Никакой синглтон, никаких проблем. Просто передайте соответствующую ссылку в конструктор тестируемого класса.
+0

Спасибо Jon. Я могу указать параметр только во время инициализации, и после этого я не хочу указывать какой-либо параметр и просто хочу использовать метод 'isLeader()' и 'getClient()' во всех классах. – AKIWEB

+0

В этом сценарии я также должен использовать DI для прохождения? – AKIWEB

+0

@AKIWEB: Да, это то, что я сделал бы. Вы можете * сделать два статических метода, один для инициализации синглтона, а другой - для его получения, но я бы этого не сделал. –

Смежные вопросы