![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| UnicornMirage |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 15.11.2005 Репутация: 1 Всего: 1 |
Добрый день всем участникам форума!
позвольте задать такой вопрос: У меня есть класс построенный по шаблону Singleton. Экземпляр этого класса используется в мультипоточном контексте (сервлетами). Для создания экземпляра класса использую фабрику:
Так как экземпляр класса MySingleton используется очень часто, разумеется мне не понравилось что при получении ссылки на него приходится вызывать синхронизированный метод getInstance. Тогда я сделал вторую фабрику:
у фабрики MegaFactory есть метод getMySingleton который не синхронизирован, тем не менее синхрнонизация используется внутри него при условии если объект класса MySingleton не создан. Потом у меня возникла идея отказаться от этой фабрики и сделать таким образом:
Скажите пожалуйста, правильно ли я сдеал? Какой из этих вариантов лучший? Или синхронизация не нужна вообще в этой задаче? Спасибо за внимание! Это сообщение отредактировал(а) UnicornMirage - 26.5.2006, 10:02 |
||||||
|
|||||||
| chief39 |
|
|||
![]() карманная тигра ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1631 Регистрация: 20.5.2005 Где: Киев Репутация: 15 Всего: 77 |
Проверка на null и создание должны быть в одном синхронайзе. Выносить проверку как во втором случае нет смысла - зачем тогда синхронайз вообще?
Ибо получится так: Первый поток проверяет - налл!!! Второй поток проверяет - налл!!! первый поток делает new второй поток (условие он-то раньше проверил) тоже делает new Сделай первый вариант, с синхронайзом внутри, чтоб меньше времени занимал(лочил) ресурс.
Это сообщение отредактировал(а) chief39 - 26.5.2006, 10:14 -------------------- Люди - это свечи. Они либо горят, либо их - в жопу!(с) |
|||
|
||||
| UnicornMirage |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 15.11.2005 Репутация: 1 Всего: 1 |
я конечно может не понял глубину проблемы - но ведь у меня как раз есть в коде единственный синхронизированный блок в котором идет проверка на null и создание экземпляра. как я полагал, если несколько потоков одновременно попали в метод MegaFactory.getMySingleton(); то только один поток сможет выполнить метод MySingleton.getInstance(); что касается приведенного Вами примера кода - разве он не будет медленнее? (если я не ошибаюсь, на вашем форуме где то обсуждалась проблема что быстрее - вынести синхронизацию в метод либо использовать внутри)... |
|||
|
||||
| allex |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 5.9.2005 Репутация: нет Всего: нет |
Вы что, сговорились все вокруг про синхронизацию синглетонов говорить?
http://jroller.com/page/sana167?entry=sync...n_in_singletons Там в обсуждении есть полезные ссылки. |
|||
|
||||
| chief39 |
|
||||
![]() карманная тигра ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1631 Регистрация: 20.5.2005 Где: Киев Репутация: 15 Всего: 77 |
Во втором примере проверка на налл ВНЕ СИНХРОНАЙЗА
Ага. А второй (тоже уверившийся ранее, что пока ещё имеем налл) подождёт, а потом тоже его выполнит. Синхронизировать сам метод будет медленнее, чем кусок кода внутри метода. Наименее возможный. Наименее возможный в нашем варианте - это проверка + создание. Вот мы их и синхронизнули -------------------- Люди - это свечи. Они либо горят, либо их - в жопу!(с) |
||||
|
|||||
| UnicornMirage |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 15.11.2005 Репутация: 1 Всего: 1 |
большое спасибо за ссылку! там есть интересная статья - Double-checked locking and the Singleton pattern в частности как я понял из нее там говорится:
значит достаточно этого подхода чтобы гарантировать корректное создание экземпляра синглетона в мультипоточном контексте? |
||||||
|
|||||||
| UnicornMirage |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 15.11.2005 Репутация: 1 Всего: 1 |
написал для себя примитивный тест чтобы посмотреть на каком этапе будет создаваться экземпляр. Вот что вышло..
Исходный синглетон:
Небольшой тест:
вот что выводится в консоль:
Удивительно! раньше я думал (и не додумался проверять) что статическая инициализация в любом классе происходит при любом первом обращении к классу. Оказывается там завязано все на ссылки? Тоесть на шаге 2 метод MySingleton.getInstance(); работает со ссылкой, и поэтому она инициилизируется.. теперь осталось протестировать в многопоточной среде. только вот как написать корректный тест - еще следует подумать. |
||||||
|
|||||||
| Beard |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 5.7.2005 Где: Санкт-Петербург Репутация: 2 Всего: 9 |
to Chief39:
А ничего, что метод статик - this-то не доступна!? Да и synchronize будет выполняться всегда - лучше уж лишнюю проверку:
|
||||||
|
|||||||
| chief39 |
|
|||
![]() карманная тигра ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1631 Регистрация: 20.5.2005 Где: Киев Репутация: 15 Всего: 77 |
Тупанул С правкой согласен (подпись Статик инициализируется при первом же её затрагивании. Вот только прикол в с наследованием - если статики есть в родителе и в сыне, то при затрагивании статика сына - инитнутся все статики сына, но не отца(!!!). А если дёрнуть какой-либо статик отца - тогда и его все статики доинитятся. Где-то была тема - раскапывали по кусочкам В общем-то решение правильное откопал Одно НО - если кто-то(из самой фактори то есть лучше уж добавить туда final модификатор Это сообщение отредактировал(а) chief39 - 26.5.2006, 14:32 -------------------- Люди - это свечи. Они либо горят, либо их - в жопу!(с) |
|||
|
||||
| Beard |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 5.7.2005 Где: Санкт-Петербург Репутация: 2 Всего: 9 |
Не совсем понял - кто может изменить, кроме самого singleton-a? |
|||
|
||||
| chief39 |
|
|||
![]() карманная тигра ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1631 Регистрация: 20.5.2005 Где: Киев Репутация: 15 Всего: 77 |
Я дописал в скобочках(пардон только что факторией обозвал - на автомате) Вот он сам и может. А ежели методов у него много - то в одном из них и может произойти бяка. (мало ли кто его будет дописывать). Но final тут не повредит. -------------------- Люди - это свечи. Они либо горят, либо их - в жопу!(с) |
|||
|
||||
| allex |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 5.9.2005 Репутация: нет Всего: нет |
UnicornMirage, а между прочим, условия инициализации класса подробно описаны в JLS.
12.4.1 When Initialization Occurs Initialization of a class consists of executing its static initializers and the initializers for static fields declared in the class. Initialization of an interface consists of executing the initializers for fields declared in the interface. Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class need not be initialized. Similarly, the superinterfaces of an interface need not be initialized before the interface is initialized. A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
|
|||
|
||||
| Beard |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 5.7.2005 Где: Санкт-Петербург Репутация: 2 Всего: 9 |
да, не повезет конторе, если она возьмет такого программера, что instance напрямую будет юзать в других методах
согласен |
||||
|
|||||
| chief39 |
|
|||
![]() карманная тигра ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1631 Регистрация: 20.5.2005 Где: Киев Репутация: 15 Всего: 77 |
Ммм.... "никогда не говори никогда" А уж если возьмут такого программера - то final не даст "не повезти" Это не к тому, что его нужно дёргать - но к тому, что если он у нас не должен изменяться по логике - тогда мы ему и запрещаем это делать. По аналогии с дядькой Эккелем: "если можем сделать не абстрактный класс, а интерфейс - делайте, обратно всегда успеется". Расфилософствовались... -------------------- Люди - это свечи. Они либо горят, либо их - в жопу!(с) |
|||
|
||||
| UnicornMirage |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 15.11.2005 Репутация: 1 Всего: 1 |
Всем большое спасибо за обсуждение, из которого удалось почерпнуть много хороших идей и ссылок!
Если бы мог, то бы поставил всем + надеюсь за меня это сделает кто нибудь.. Это сообщение отредактировал(а) UnicornMirage - 27.5.2006, 17:38 |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |