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

я есть требование для ленивой загрузки ресурсов в параллельной среде. Код для загрузки ресурсов должен быть выполнен только один раз.

ОбеДвойная проверка блокировки (используя JRE 5+ и ключевое слово volatile) иИнициализация по требованию владельца похоже, хорошо подходит для работы.

Просто глядя на код, идиома держателя инициализации по требованию кажется чище и эффективнее (но, я думаю, здесь). Тем не менее, мне придется заботиться и документировать шаблон на каждом из моих синглетонов. По крайней мере, мне было бы трудно понять, почему код был написан на месте так ...

Мой вопрос здесь: какой подход лучше? И почему? Если ваш ответ - нет. Как бы вы справились с этим требованием в среде Java SE?

альтернативы

Могу ли я использовать CDI для этого, не навязывая его для всего моего проекта? Есть какие-нибудь статьи?

Ответы на вопрос(3)

ого элемента, поэтому для каждого экземпляра нельзя использовать элементы с отложенной загрузкой. Двойная проверка блокировки накладывает когнитивное бремя на всех, кто должен смотреть на класс, так как легко ошибиться тонкими способами. Раньше у нас были разные проблемы, пока мы не инкапсулировали шаблон в служебный класс внаша библиотека параллелизма

У нас есть следующие варианты:

Supplier<ExpensiveThing> t1 = new LazyReference<ExpensiveThing>() {
  protected ExpensiveThing create() {
    … // expensive initialisation
  }
};

Supplier<ExpensiveThing> t2 = Lazy.supplier(new Supplier<ExpensiveThing>() {
  public ExpensiveThing get() {
    … // expensive initialisation
  }
});

Оба имеют одинаковую семантику в отношении использования. Вторая форма делает любые ссылки, используемые внутренним поставщиком, доступными для GC после инициализации. Вторая форма также поддерживает таймауты со стратегиями TTL / TTI.

 Alex Miller01 июн. 2011 г., 17:36
иногда называемый шаблоном виртуального прокси ... Реализация прекрасно иллюстрирует решение проблемы «стада громов», когда несколько абонентов запрашивают один и тот же ресурс, но вы хотите получить ресурс только один раз.
 Jed Wesley-Smith03 июн. 2011 г., 01:07
спасибо Алекс, мы много его используем, хорошо работает.

я бы пошел с инициализацией по требованию владельца. Я считаю, что блокировка с двойной проверкой - устаревшая и уродливая реализация.

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

Решение Вопроса
 djg31 мая 2011 г., 17:12
Конечно, это работает.
 Anthony Accioly31 мая 2011 г., 18:19
@djg Звучит достаточно хорошо для меня. Но есть ли способ отложить вычисления еще дальше? Например, скажем, что я хочу загрузить несколько разных ресурсов независимо друг от друга. Используя этот шаблон, мне пришлось бы писать разные перечисления. Есть ли способ достичь этого только с одним перечислением? СкажемElvis с участиемINSTANCE1.getAge() а такжеINSTANCE2.getAge(), Могу ли я сделать так, чтобы они загружались независимо друг от друга потокобезопасным способом?
 djg31 мая 2011 г., 18:37
Правильно. Я думал об отдельных перечислениях / синглетонах. Если у вас есть несколько «INSTANCE», то ваш конструктор вызывается один раз для каждого. Насколько я понимаю, это было нежелательно.
 Anthony Accioly31 мая 2011 г., 16:58
Приятно. Но я не уверен, что понял, как это работает. СкажемElvis.getAge() нужны довольно интенсивные операции, которые я хочу отложить как можно дольше и выполнить только один раз. Где бы я положил свой код загрузки? В конструкторе Enum?
 djg31 мая 2011 г., 20:37
Если вы обрабатываете ленивую загрузку (и синхронизацию) значений в вызове метода, вы обходите преимущества синглтона enum. Я не уверен во всех ваших требованиях, но я бы предложил интерфейс, который каждый из вас мог бы реализовать в отдельных классах синглтоновых перечислений. Или только один синглтон, который включает в себя все ресурсы (при условии, что вы можете обрабатывать производительность «все сразу» во время загрузки).

Ваш ответ на вопрос