2015-04-27 4 views
0

Я в основном ищу механизм кэширования для пользователей HelperWrapper. Правильно ли это использование двухместного синглета?Правильно ли это использование двухэлементной проверки?

final class HelperWrapper { 
  private static volatile Helper helper = null; 
  
  public static Helper getHelper() { 
    if (helper == null) { 
      synchronized (HelperWrapper.class) { 
        if (helper == null) { 
          helper = new Helper(); 
        } 
      } 
    } 
    return helper; 
  } 
} 

Я знаю, что это не помешало бы кому-либо создавать свои собственные объекты Helper, но это не цель.

Дополнительная информация:

  • Я не могу изменить класс Helper, чтобы конструктор приватным. Я тоже этого не хочу.
  • требования диктуют, что помощник не должен быть охотно инстанцирован
+0

Связанные записи: [Пункт 3 из эффективной Java] (http://www.informit.com/articles/article.aspx?p=1216151&seqNum=3) – JonK

+0

Я не могу изменить исходный код Helper, поэтому я не могу сделать его конструктор частный. Я не пытаюсь помешать другим создавать экземпляр собственного помощника. – Ares

+0

@VinceEmigh Двойная проверенная блокировка больше не нарушена, так как Java 5. – CKing

ответ

2

По состоянию на Java 5, то реализации is safe. Тем не менее, рекомендуется использовать внутренний класс вместо:

final class HelperWrapper { 
    private static final class DeferredLoader { 
    public static final Helper HELPER_INSTANCE = new Helper(); 
    } 

    public static Helper getHelper() { 
    return DeferredLoader.HELPER_INSTANCE; 
    } 
} 

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

+0

Я до сих пор не понимаю, в чем смысл обертки Singleton, когда Помощник не имеет частного конструктора? – CKing

+0

Я не могу говорить за @Ares. Просто может быть, что сторонняя сторона предоставляет «Помощник», а @Ares обнаружил, что они хотят потреблять в виде сингла (возможно, по соображениям производительности). Вы правы, что не можете предотвратить прямую инстанцирование. –

+0

@bot Существует несколько случаев, когда требуется один экземпляр какого-либо объекта в заданном контексте, хотя он не должен быть одиночным для всего vm. Например, если класс может использовать ExecutorService, он может потребовать, чтобы принудительное использование одного объекта для этого класса. Это не означает, что никто из jvm не должен иметь возможность создавать экземпляр. –

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