Пользователь
0,0
рейтинг
9 июня 2008 в 18:30

Разработка → Реализация Singleton в JAVA

В этой статье я хочу затронуть тему одного из наиболее распространенных паттернов объектно-ориентированного программирования – Singleton. Но в данном случае я не буду описывать преимущества/недостатки и области применения этого паттерна, а попытаюсь изложить свой взгляд на его имплементацию в JAVA.

Общие сведения
Паттерн Singleton гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.


Область применения
1.) В системе должно существовать не более одного экземпляра заданного класса.
2.) Экземпляр должен быть легко доступен для всех клиентов данного класса.
3.) Создание объекта on demand, то есть, когда он понадобится первый раз, а не во время инициализации системы.

Реализация (JAVA):
На данный момент существуют несколько вариантов реализации со своими недостатками и преимуществами. В них мы и попробуем сейчас разобраться.

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

У этого решения есть единственный недостаток – оно не работает в многопоточной среде и поэтому не подходит в большинстве случаев. Решение подходит исключительно для однопоточных приложений.

Не беда, скажите вы, и предложите следующее решение.

Вариант второй:
Вариант второй

И вы будете правы, так как проблему многопоточности мы решили, но потеряли две важные вещи:
1. Ленивую инициализацию (Объект instance будет создан classloader-ом во время инициализации класса)
2. Отсутствует возможность обработки исключительных ситуаций(exceptions) во время вызова конструктора.

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

Далее возникают 2 варианта решения.
1.) Использование внутреннего класса(решение Била Пью(Bill Pugh) “Initialization on Demand Holder”).
2.) Использование синхронизации.

Начнем с Била Пью.

Вариант третий:
“Initialization on Demand Holder”
Вариант третий

В данном случае мы полностью решили проблему ленивой инициализации – объект инициализируется при первом вызове метода getInstance(). Но у нас осталась проблема с обработкой исключительных ситуаций в конструкторе. Так что, если конструктор класса не вызывает опасений создания исключительных ситуаций, то смело можно использовать этот метод.

Синхронизация
Этой части я хотел бы уделить особое внимание. Можно было бы подойти к данному вопросу с заголовком «synchronized – мифы и реальность».

И так, самый прямолинейный метод.

Вариант четвертый:
Вариант четвертый
У этого варианта есть только один недостаток. Синхронизация полезна только один раз, при первом обращении к getInstance(), после этого каждый раз, при обращении этому методу, синхронизация просто забирает время. Что можно сказать по этому поводу? Ну, во-первых, если вызов getInstance() не происходит достаточно часто (что значит «достаточно часто» решать вам), то этот метод имеет преимущество перед остальными – прост, понятен, лениво инициализируется, дает возможность обрабатывать исключительные ситуации в конструкторе. А во-вторых, синхронизация в Java перестала быть обременительно медленной настолько, насколько ее боятся. Ну что еще для счастья надо?

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

Наиболее распространенный способ — «Double-Checked Locking». В своем оригинальном варианте:
Double-Checked Locking

Не работает! Почему? Это отдельная тема, но для интересующихся могу посоветовать прочитать эту статью http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.

Но не надо совсем отчаиваться, в JAVA 5 проблему решили, используя модификатор volatile. На данный момент решение выглядит так:

Вариант пятый:
Вариант пятый

Не смотря на то, что этот вариант выглядит как идеальное решение, использовать его не рекомендуется т.к. товарищ Allen Holub заметил, что использование volatile модификатора может привести к проблемам производительности на мультипроцессорных системах. Но решать все же вам.

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

Подводные камни
1. Наследование
В подавляющем большинстве случаев в Singleton классах наследование не нужно и, более того, излишне и является следствием over-design. Да и реализация наследования имеет определенные сложности, учитывая, что и сам instance и метод getInstance() статические.
Поэтому, я рекомендую использовать модификатор final и запретить наследование данного класса, если нет особой необходимости в обратном.

2. Две и более виртуальных машины
Каждая виртуальная машина создает свою копию Singleton объекта. И хотя на первый взгляд это выглядит очевидным, во многих распределенных системах, таких как EJB, JINI и RMI все не так просто. Когда промежуточные уровни скрывают (делают прозрачными) распределенные технологи, бывает трудно сказать, где и когда инициализирован объект.
3.Различные Class Loader-ы
Когда 2 class loader-а загружают класс, каждый из них может создать свою копию Singleton-а(в тех случаях, когда instance инициализируется class loader-ом ). Это особенно актуально в использовании сервлетов(servlet), так как в некоторых имплементациях серверов приложений(application server) каждый сервлет имеет свой class loader.

Существует еще ряд проблем, которые менее актуальны (такие как технология reflection и имплементация интерфейсов Cloneable и Serializable), и не будут мною рассмотрены в силу своей экзотичности в сфере применения Singleton классов. Но, в любом случае, с радостью отвечу на любые вопросы к этому материалу.

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

Спасибо за внимание.
shalomman @shalomman
карма
64,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (93)

  • +3
    хорошая статья, пишите больше)
    • 0
      небольшой экскурс по паттерну Singleton
      • +2
        Не думаю, что стоит брать этот экскурс, как хороший источник информации. Использованный в нем пример реализации Singleton на java во-первых не работает, а во-вторых использует имена переменных типа "test1".
  • 0
    Спасибо за статью.
    Может быть стоит переместить ее в блог по Java: http://habrahabr.ru/blog/java/ ?
    • +1
      Я не думаю, не смотря на то, что статья Java-ориентированная, она все же больше относиться к "Совершенному коду", на мой взгляд.
      • 0
        А у вас нет желания опубликовать серию статей по Java? Это было бы очень полезно.
        • +6
          Это была пробная статья. Если будет достаточно читателей, то я напишу еще несколько статей относящихся к Java программированию.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Видимо все же напишу=) И дабы не оставлять в вас сомнения, эту статью я написал сам. Используя некоторые источники, разумеется.
  • +3
    Кстати, добавте в статью те случаи, когда Singelton является антипаттерном. Например, когда в него засовывают "глобалбные" переменные.
    • 0
      В данной статье я специально опустил эти детали и сконцентрировался только на реализации singleton функционала. Но я с вами согласен, есть множество неправильных использований синглтона, которые только вредят дизайну.
      • 0
        Как раз знание этих вещей поможет писать совершенный код. Вам был бы огромный респект и плюс в карму (хотя я уже плюсанул :-)), если бы вы изучили эти случаи и дополнили ими статью.
        • 0
          Этих случаев достаточно много, и они, скорей всего, относятся к несовершенному дизайну, а не к несовершенному коду. Возьмем ваш пример - "..когда в него засовывают "глобалбные" переменные..", с точки зрения кода, все может работать отлично, но с точки зрения дизайна - ряд проблем на лицо.
          • +1
            Ну тогда ждем отдельную статью по дизайну :-)
    • 0
      не согласен. синглтон прекрасно может хранить глобальные переменные.

      Наглядный пример: паттерн Registry
      • 0
        Где ж тут про переменные сказано?
  • 0
    Статья интересная безусловно. Одно замечание - я бы вместо термина "аппликация" использовал "приложение". Режет глаза термин.
    • 0
      Действительно режет=) Исправил, спасибо.
  • +2
    огромное спасибо за статью.был бы вам очень признателен,если бы вы писали еще что нибудь про Java:)
  • 0
    Когда делали скриншоты с Эклипса, то 2, 3 и 4я картинки получили размазаны.
    • 0
      Нет, у меня все картинки в хорошем качестве. Видимо хабр, подгоняя картинки под какие-то свои размеры, слегка растягивает их, тем самым вызывает эффект смазывания.
  • 0
    Почему в первом примере для многопоточной среды нельзя сделать вызов getInstance() синхронизованым (synchronized) ? Это решило бы сразу все проблемы.
    • 0
      Именно это я и сделал в 4-ом варианте решения.
      • 0
        Ну у вас какой-то обходной путь. Как только вы поняли, что оно не подходит для multi-thread, вы начали не пойми что придумывать, когда надо только добавить "synhronized"
        • 0
          Не буду с вами спорить.
          • 0
            Да. Спорить наверное не нужно, ибо DOKA сделал неплохое замечание. Я также когда читал, споткнулся на этом месте. Ну раз не многопоточный, то стало быть и желательно одним предложением написать почему он такой и добавить, что логично, разумеется, воткнуть synchronized и закрыть вопрос. Сославшись на то, что такой случай будет рассмотрен ниже и у него есть свой нюанс.

            Второй момент который чуть резанул глаз, это фраза - Реализация Singleton в JAVA. Я не знаю прав я или нет с точки зрения моего интуитивного ощущения русского языка, но когда я вижу фразу ..В Java… я ожидаю, что это УЖЕ реализовано внутри самой платформы и человек просто описывает как там это сделано. Если же речь идёт о том как самому реализовать что-то средствами языка, я ожидаю увидеть оборот ...НА Java.. То есть - как мне реализовать это на языке Java.

            Что же касается статьи в целом, то наверное это одна из самых толковых технических статей на Хабре за долгий период. Обычно люди, когда вставляют куски кода в статью, вырывают их из контекста и этот контекст не описывают. То есть пишут в духе ... я вот вчера ночью, лихорадочно кодируя (препарируя вирус...)... открыл для себя, что тут можно было вставить вот такой крутой оператор... а посему на утро хочу поделиться этим с хабра-людьми. Это всё хорошо, но... Что кодировал? Куда вставил? Зачем вставил и кому это нужно?
            У вас действительно чётко и внятно описан ходовой и нужный паттерн, и приведены основные варианты его реализации с их плюсами и минусами. Статья логически закончена и реально полезна разработчику. Просто как букварь. Лан, не буду тут раcшаркиваться :-), но что хотел сказать, то сказал.
        • 0
          А performance?
          Если getInstance() вызывается в циклах постоянно?
          • 0
            Если надо вызывать из цикла, то можно использовать вар. №5. В остальных случаях в угоду читаемости следует использовать sinhronized на метод. И что-то мне подсказывает, что результат в действительности будет не сильно различаться.
            • 0
              эм... а не кажется что вызов getInstance() в циклах для singleton объекта мягко говоря не правильна с точки зрения архитектуры самой программы
              • 0
                Зависит от цикла. Если простой for то действительно не правильно, а если идет логический цикл процесса с кучей логики, то никуда от этого не денешься.
          • НЛО прилетело и опубликовало эту надпись здесь
            • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Ещё бы кто-нибудь на Хабре написал beginners tutorial по Hibernate.. Было бы клёво :)
    • 0
      Будет время - напишу. Чем вас не устраивает туториал, который находится на оффсайте Hibernate? Или этот, например, если вам нужно на русском языке http://www.javaportal.ru/java/articles/h….
      • 0
        Могу предположить, что а) русский вариант просто не был найден (я вот пару лет назад пытался - не получилось) или б) в случае публикации на хабре можно будет уточнить у автора неясные моменты.
  • +2
    О реализации синглетонов на C++ хорошо написано у Александреску. Может, и явистам будет интересно почитать.
    • +1
      Нет. В C++ совершенно другая семантика работы с объектами.
  • 0
    отличная статья
  • +1
    В Scala ("the new java") это реализовано на уровне синтаксиса языка - можно объявлять сразу object, а не class
    • 0
      Это не совсем то же самое — хочется ленивой инстанциации
      • 0
        это порочное желение.
        Если хочется ленивой загрузки, значит у объекта есть жизненный цикл (например, взаимодействие с каким-нубдь ресурсом или большие требования памяти / cpu). А это уже по определению не Singleton
        • 0
          расскажите это заказчику, который хочет чтобы окошко приложение отрисовывалось через 2 секунды после запуска и его не волнует что правильно, а что нет. Вместе с тем некоторые синглтоны вполне могут инициализироваться от чего-нибудь медленного, да хотя бы от чтение с диска.
          • 0
            это не проблема, просто не надо этого делать в конструкторе
            • 0
              И в каком тогда месте вы собираитесь инициализировать синглтон?
              • 0
                это для вас проблема?! в любом. можно явно методом init(), можно неявно при обращении к любому методу, паттерны кэширования никто не отменял.
  • 0
    круто, спасибо! :)
    большую часть информации я и так знал, но некоторые моменты были познавательными.

    IJ Idea, кстати, автоматом по дефолту генерит второй вариант
  • +2
    было бы здорово если бы в подобном очень дружелюбном изложении
    на хабре написал бы кто-нибудь пару статей и про другие основные шаблоны
    а конкретно с примерами их использования в своих проектах

    книжки книжками, но там всегда одни и те же везде примеры - как будто все только и делают, что
    клепают интернет магазины и студентов в базу заносят
    • 0
      Полностью согласен. Паттерны тоже неким образом относятся к совершенному коду. Было бы инетесрено узнать об особенностях их применения на практике, т.к. в моей компании нет людей, способных понять простейшие принципы разработки программного обспечения в команде.
  • 0
    Отличная статья! Автору спасибо! Побольше бы таких :)
  • 0
    с нетерпением буду ждать продолжение и о яве, и по тематике блога.
    автору — спасибо!
  • 0
    Будет нелишне добавить
    public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
    }
    • +1
      я думаю, что все-же лишне, тк метод clone() является protcted в Object. И раз уж всеравно, в основном, все Синглтоны будут final, то перегружать метод clone() не имеет смысла.
  • 0
    Спасибо.
  • +1
    Статья интересная, плюсанул, но. Но нужно помнить об осторожности и технике безопасности. Когда даете детям в руки такую игрушку, очень важно упомянуть, как НЕ НАДО ей играться, а то так сдуру и тесты сломать можно.
    Синглтон выглядит очень привлекательно, а на самом деле во многих популярных случаях это все-таки антипаттерн.
    • +1
      Синглетон полезный и нужный паттерн для чётко очерченных случаев, тщательно описанных в его описании. Называть его антипаттерном, это как называть кухонный нож вредным инструментом на том простом основании, что им можно кого-то зарезать. Ну да, наверное можно, но если бы он сопровождался инструкцией, там было бы внятно написано, что им нужно картошку чистить. И только.

      В противном случае большинство окружающих нас вещей можно было бы легко зачислить в антипаттерны. Авто, качели, табуретки... Антипаттерн – это неправильное использование нужной и полезной вещи. Из этого абсолютно никак не следует, что мы не должны знать и шарахаться правильного применения нужных и полезных вещей. :-)
  • 0
    enum Singleton {
    INSTANCE;
    public static Singleton getInstance() { return INSTANCE; }
    }
    • +1
      минусующему предлагаю почитать мнение Блоха, который, как ни странно, тоже считает, что a single-element enum type is the best way to implement a singleton.
      • 0
        Действительно, очень интересный вариант. Испаравил социальную несправедливость, где только мог. Спасибо.
        • 0
          Честно говоря, я не могу доказать, что в данном случае гарантирована безопасность в многопоточной среде, но я на 95% уверен, что авторы спецификации Java5 это предусмотрели. Надо будет порыться в спецификации или дизассемблировать какой-нибудь пример.
          • 0
            примерчик дизассемблировал, все нормально там с многопоточностью, по структуре реализация enum это развитие второго варианта, со всеми наворотами enum'ов, которые, цитируя Блоха, добавляют лаконичность синтаксического сахара, сериализацию "из коробки", и серьезную безопасность, в т.ч. от разных изощренных атак.
            • 0
              Если честно, то я так и думал. Вот только сериализация в синглтонах обычно только проблемы приносит=) Ну и, наверно, я редко сталкивался с атаками на мои синглтоны..хотя, всегда лучше перебдеть, чем недобдеть=)
    • 0
      в
      enum Singleton {
      INSTANCE;
      public static Singleton getInstance() { return INSTANCE; }
      }


      public static Singleton getInstance() { return INSTANCE; }
      строчка лишняя имхо.

      Если уж enum , то Singleton.INSTANCE
      • 0
        не совсем так, пользователь не обязан знать, что singleton реализован как enum, он просто пользуется им как обычным классом-синглтоном вызывая getInstance(), который может даже интерфейс возвращать.
  • 0
    Пара замечаний по 5 пункту.
    1. volatile вообще-то считается самым быстрым способом синхронизации в Java. Быстрее бывает только полное отстуствие синхронизации. Более того: в режиме чтения, который используется в примере, скорость доступа к volatile переменной практически не отличается от скорости доступа к несинхронизированной переменной. Товарищ Allen Holub был здесь неправ, или его неправильно поняли.
    2. Корректная работа данного когда под Java версии < 1.5 тоже не гарантируется :)
    Подробнее можно почитать у Билла Пью
    • 0
      http://www.ibm.com/developerworks/ru/library/j-jtp03304/index.html
      Здесь очень неплохо написано про volatile, final и синхронизацию, советую прочитать
  • 0
    Хотелось бы добавить пару основных вариантов использования синглтона. В некоторых случаях Singleton используется для экономии ресурсов, а в некоторых для реального контроля количества инстансов объекта в системе. В первом случае система проглотит неумелую реализацию без особых проблем, например если синглтон, являющийся фабрикой для создания объектов другого типа, создастся в каждом класслоадере, скорее всего это не будет критической проблемой, кроме конечно проблемы "чистого" решения с точки зрения оптимизации. Если речь идет о контроле объектов, например, конфигурационные параметры системы, которые могут динамически обновляться, то тут конечно грамотная реализация очень важна. Плюс если приложение кластерное, к вариантам реализации синглтона добавляются такие как, per cluster basis или per node basis, что опять же зависит от требований к классу. Вообщем есть о чем подумать на досуге, если вдруг обнаружилось, что класс можно реализовать синглтоном.
  • 0
    Вот ещё хорошая статья (да и вообще сайт хороший) на эту тему :)
    • 0
      чёрт, вот ссылка: http://skipy.ru/technics/singleton.html
  • 0
    Отличная статья! Но есть ещё один способ реализации синглетона - вызовы можно обрабатывать в одной нитке, скажем в Event Dispath Thread. Если запрос к синглетону идет из другой нити, его можно обработать, скажем, используя SwingUtilities.invkoeAndWait(...).

    Такое решение подходит, когда _почи_ все вызовы идут в одном потоке.
  • –1
    Неплохая вообщем-то статья, но растянутая, и слишком много как мне кажется уделено времени реализация однопоточности, когда чаще всего все-таки Singleton реализуются в многопоточности(иначе смысла большого нету использоваться этот паттерн). Хотелось бы увидеть еще другие паттерны, более сложные, и но не менее востребованные - фабрика, мосты, накопитель и т.д.

    P.S. давно хотел написать пару статень по java. плюс пару статей по сертификации у Sun, если кому интересно, но пока к сожалению не могу.
    P.S.S. интересный 5-ый вариант реализации, как-то не пользовался таким, обычно просто использовал синхранизацию на get методе, возьму на вооружение
    • 0
      Однопоточность обсуждается в одном варианте и одномн абзаце. Куда уж короче.
      PS использовать синхронизацию на get() не имееет никакого смысла. Пора менять концепцию=)

      PSS но, всеравно спасибо за позитивно-конструктивный комментарий
      • 0
        помойму вы сами себе противоречите, почему же не имеет смысла использовать сихнхронизацию на get ? Если у вас в 4А-ом примере используется сихронизация именно на get методе. Хотя конечно реализация 4Б-ым вариантом намного логичней. Реализация 1,2,3 фактически одно и тоже, и расматривает однопоточные решения. Различаются только способом создания объекта, и возможности обработки исключения на этапе инициализации объета или конструктора.
        • 0
          варианты 2,3 работают в многопоточной среде и не используют синхронизацию
          • 0
            Да ладно )) я вам могу как минимум привести 2-3 примера где вариант 2,3 не будет работать в многопоточной среде, и скорее всего выволется по exception'у. К примеру один поток запускает этот класс для инициализации, и тут вдруг срабатывает FullGC, все объекты и потоки переходят опять в состояние Runnable, и после этого JVM выбирает потом которые первый пойдет на выполнения, и нету гарантии что первый потом пойдет именно тот который был до FullGC. Дальше, если инициализация объекта достаточно затратное время -допустим коннект к базе данных, или еще что-нибудь. То я вас уверяю что без сихнронизации один поток скорее всего получит null в ответ, или выволиться StaticInitializationException. Причем еще такая реализация без сихнронизации может сильно отличаться в разных средах допустим на Solaris или Windows
            • 0
              я не понял вашего примера, но могу смело вам сказать, что вы не правы. В вариантах 2,3 объект инициализируется класслоадером, поэтому null никто не получит.

              И уж точно непричем здесь Solaris и Windows=) Я согласен, что есть некороые различия в виртуальных машинах, но не на таком уровне.
              • 0
                просто я разрабатываю системы реального времени со сверх большой нагрузкой, и каких только "не может быть" у нас не было, и каких разниц только в реализациях и поведения Solaris, Linux не было.
                А системы отличаются очень сильно. К примеру Windows закрывает сокеты сразу же, а solaris вообще не закрывает сокеты, а переводит их в состояние TIME_WAIT(и таких примеров куча).
                По поводу примеру, какой смысл надеятся на правильнную реализацию static class loader при многопоточном режиме ? я почти уверен что можно сэмулировать StaticInitializationException при подходве 2-3 в многопоточном обращении к объекту.
                • 0
                  Если уж вы разарабатываете "системы реального времени со сверх большой нагрузкой", то должны занть цену синхронизации.
                  • 0
                    Цена синхронизации конечно важна, но намного важней чтоб не нарушалась целостность данных при многопоточной работе.
                    Мне не очень понравился пятый пример, все не мог понять чем. Нашел на javaworld.com, плюс на ibm.com, и я нашел объяснения - того что мне не нравится.
                    1) то что в 5-ом примере используете двойную проверку - это хорошо, если бы ее не было внутри сихнронизованной секции, это бы вообще работало не корректно и не был даже синглтон.
                    2) чем плох все-таки 5-ый пример в отличии от синхронизации именно метода getInstance(), вот что пишет ibm:
                    The theory behind double-checked locking is perfect. Unfortunately, reality is entirely different. The problem with double-checked locking is that there is no guarantee it will work on single or multi-processor machines.

                    The issue of the failure of double-checked locking is not due to implementation bugs in JVMs but to the current Java platform memory model. The memory model allows what is known as "out-of-order writes" and is a prime reason why this idiom fails.
                    Как раз что и я и говорил - при работе на реальных JVM в исключительных ситуациях.
                    К примеру вот такой вариант будет работать всегда:
                    public static Singleton getInstance()
                    {
                    if (instance == null)
                    {
                    synchronized(Singleton.class) { //1
                    Singleton inst = instance; //2
                    if (inst == null)
                    {
                    synchronized(Singleton.class) { //3
                    //inst = new Singleton(); //4
                    instance = new Singleton();
                    }
                    //instance = inst; //5
                    }
                    }
                    }
                    return instance;
                    }
                    Большая часть инфы и пример взят от сюда:
                    http://www.ibm.com/developerworks/library/j-dcl.html
                    Так же эту ситауацию еще расматривают тут
                    http://www.javaworld.com/jw-01-2001/jw-0112-singleton.html?page=6
                    Думаю на это дискуссия закончилась ) я не мог точно объяснить почему это плохо, теперь объяснение есть, поэтому я немного не в ту степь пошел при возникшем споре.
                    • 0
                      Чтож, очень обидно, что вы начинаете спор не прочитав статью внимательно. Как и ваше утверждение на тему многопоточности 2 и 3 варианов. Так и здесь, я написал, что Double-checked locking в своем оригинальном варианте не работает, но начиная с Java 5, починили модификатор volatile, и если его использовать, то Double-checked locking заработает. Жаль, что вы читаете по диагонали. Спор с вами мне стал не интересен, если хотите задавать вопросы - пожалуйста, но спорить с вами более я не буду.
            • 0
              2,3 вполне будут работать - classloader синхронизирует инициализацию класса. Иначе корректная инициализация классов в multithreaded программе была бы в принципе невозможна.
  • 0
    Сначала подумал, что какой-то детский обзор сингтона, но хорошо что продолжил читать :)
    Неплохо разобрали варианты шаблона
  • 0
    подозреваю, что если в последнем варианте synchronized блок вынести в отдельную процедуру, то все сработает.
  • 0
    неплохо. спасибо. ждем остальных паттернов. было бы интересно почитать и обсудить с народом потом.
  • 0
    Вот очень интересная статья на тему signleton:
    www.javenue.info/post/83

    Основная идея в том, что диспетчеризация вызова метода работает гораздо быстрее чем условный оператор (меньше тиков).
    Говоря по простому: на реальном параллельном выполнении мы получаем огромную экономию процессорного времени.
    Уверен, статья будет интересна абсолютно всем настоящим Java-программистам.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      а какая разница?
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          нет, не должно. будет работать также.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              что-то я тебя не особенно понимаю. Напиши, пожалуйста, код и покажи где не будет блокировки.
              • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Если instance!=null — то до synchronized итак не дойдет юудет сразу return instance
      • НЛО прилетело и опубликовало эту надпись здесь

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