powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронизация синглетона
25 сообщений из 36, страница 1 из 2
Синхронизация синглетона
    #33753539
unicornmirage
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день всем участникам форума!

позвольте задать такой вопрос:
У меня есть класс построенный по шаблону Singleton. Экземпляр этого класса используется в мультипоточном контексте (сервлетами). Для создания экземпляра класса использую фабрику:

Код:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class MySingleton {
        private static MySingleton oneInst;

        private  MySingleton () {} 

        /**
         * данный метод я синхронизирую чтобы изключить возможность множественных вызов
         * из разных потоков
         */
        public static synchronized  MySingleton getInstance () {
                if(oneInst == null) {
                        oneInst = new  MySingleton ();
                }
                return oneInst ;
        }
}


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

Код:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class MegaFactory {
        private static MySingleton oneInst;

       public static  MySingleton getMySingleton() {
              if (oneInst == null) {
                      oneInst = MySingleton.getInstance();  // синхронизация используется один раз
              }
              return  oneInst;
       }
}


у фабрики MegaFactory есть метод getMySingleton который не синхронизирован, тем не менее синхрнонизация используется внутри него при условии если объект класса MySingleton не создан.

Потом у меня возникла идея отказаться от этой фабрики и сделать таким образом:
Код:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class MySingleton {
        private static MySingleton oneInst = new MySingleton ();

        private  MySingleton () {} 

        /**
         * данный метод уже не синхронизирован
         */
        public static MySingleton getInstance () {
                return oneInst ;
        }
}


Скажите пожалуйста, правильно ли я сдеал? Какой из этих вариантов лучший? Или синхронизация не нужна вообще в этой задаче?
Спасибо за внимание!
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33753546
unicornmirage
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
извините, теги оказывается другие тут...

У меня есть класс построенный по шаблону Singleton. Экземпляр этого класса используется в мультипоточном контексте (сервлетами). Для создания экземпляра класса использую фабрику:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class MySingleton {
private static MySingleton oneInst;

private MySingleton () {}

/**
* данный метод я синхронизирую чтобы изключить возможность множественных вызов
* из разных потоков
*/
public static synchronized MySingleton getInstance () {
if(oneInst == null) {
oneInst = new MySingleton ();
}
return oneInst ;
}
}

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class MegaFactory {
private static MySingleton oneInst;

public static MySingleton getMySingleton() {
if (oneInst == null) {
oneInst = MySingleton.getInstance(); // синхронизация используется один раз
}
return oneInst;
}
}

у фабрики MegaFactory есть метод getMySingleton который не синхронизирован, тем не менее синхрнонизация используется внутри него при условии если объект класса MySingleton не создан.

Потом у меня возникла идея отказаться от этой фабрики и сделать таким образом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class MySingleton {
private static MySingleton oneInst = new MySingleton ();

private MySingleton () {}

/**
* данный метод уже не синхронизирован
*/
public static MySingleton getInstance () {
return oneInst ;
}
}

Скажите пожалуйста, правильно ли я сдеал? Какой из этих вариантов лучший? Или синхронизация не нужна вообще в этой задаче?
Спасибо за внимание!
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33753813
ponomarevvb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, в последнем варианте всё равно надо синхронизировать метод.
--С уважением, ponomarevvb--
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33754401
OU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
OU
Гость
2 unicornmirage:
В первом случае все правильно, код должен быть synchronized. Второй вариант не имеет смысл (с точки зрения того для чего вы его писали), так как метод getMySingleton() все равно вызывает внутри себя synchronized метод getInstance(). Третий вариант правильный.

Первый вариант хуже третьего в производительности (так как поток должен все равно выполнить проверку условия), но лучше в обслуживании (можно обрабатывать исключения).
Третий вариант лучше первого в производительности, но хуже в обслуживании (данный метод инициализации не позволяет обрабатывать исключения).
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33754462
unicornmirage
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OU.
Третий вариант лучше первого в производительности, но хуже в обслуживании (данный метод инициализации не позволяет обрабатывать исключения).

а какие здесь могут возникнуть исключения? конфликт доступа?
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33754654
OU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
OU
Гость
http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33754899
Jozic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
     public   static  MySingleton getInstance() {
         if  ( oneInst ==  null  ) {
             synchronized  ( MySingleton. class  ) {
                 if  ( oneInst ==  null  ) {
                    oneInst =  new  MySingleton();
                }
            }
        }
         return  oneInst;
    }
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755098
SqlLoader
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Jozicа так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
     public   static  MySingleton getInstance() {
         if  ( oneInst ==  null  ) {
             synchronized  ( MySingleton. class  ) {
                 if  ( oneInst ==  null  ) {
                    oneInst =  new  MySingleton();
                }
            }
        }
         return  oneInst;
    }


Так нельзя. Читай про Double-checked locking.
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755361
Jozic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlLoaderТак нельзя. Читай про Double-checked locking.спасибо :)
http://www-128.ibm.com/developerworks/java/library/j-dcl.html
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755717
Фотография Кувалдин Роман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мистер Блох советует делать это вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
 public   class  FooSingleton
{
     private  FooSingleton()
    {
        // тело конструктора
    }

     private   static   class  FooHolder
    {
         static   final  FooSingleton instance =  new  FooSingleton();
    }

     public   static  FooSingleton getInstance()
    {
         return  FooHolder.instance;
    }

Joshua BlochThe idiom takes advantage of the guarantee that a class will not be initialized until it is used [JLS, 12.4.1]. When the getFoo method is invoked for the first time, it reads the field FooHolder.foo, causing the FooHolder class to get initialized. The beauty of this idiom is that the getFoo method is not synchronized and performs only a field access, so lazy initialization adds practically nothing to the cost of access. The only shortcoming of the idiom is that it does not work for instance fields, only for static fields.


======================
- Я подхожу к клетке с медведем панда...
Видите, какие у него черные круги под глазами?!
Медведь панда как бы всем своим видом говорит нам: "Не бухайте!"
======================
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755945
OU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
OU
Гость
2 Роман:
По видимому код не полный, т.к он не совсем подходит под приведенное описание. В частности нет members getFoo и foo. Если не затруднит то не могли бы вы привести ссылку на оригинал.
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755953
Фотография Кувалдин Роман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OU2 Роман:
По видимому код не полный, т.к он не совсем подходит под приведенное описание. В частности нет members getFoo и foo. Если не затруднит то не могли бы вы привести ссылку на оригинал.

foo = instance;
getFoo = getInstance;

Извини, бездумно скопировал текст с Блоха, а исходники чуточку переименовал.

Саму книгу можно скачать из библиотеки уважаемого Грасоff-а:

http://lib.swapj.net/books/effective-java-programming-language-guide.zip

Глава 9, задача 48.
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33755979
OU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
OU
Гость
2 Роман:

спасибо, пойду гляну
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33756391
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кувалдин РоманМистер Блох советует делать это вот так:
Решение изящное, но возможно по невежеству возникают два вопроса. Нельзя ли коротко прояснить их?

1. Зачем делать внутренний класс? Статический член того же класса, по идее, должен сработать не хуже, инициализируясь при первом использовании класса, то есть в большинстве случаев - при первом вызове getInstance().

2. А дает ли это реальный выигрыш, учитывая, что где-нибудь внутри неявно вызванного getClass() будет та же самая синхронизация?
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33756934
Фотография Кувалдин Роман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer Кувалдин РоманМистер Блох советует делать это вот так:
Решение изящное, но возможно по невежеству возникают два вопроса. Нельзя ли коротко прояснить их?

1. Зачем делать внутренний класс? Статический член того же класса, по идее, должен сработать не хуже, инициализируясь при первом использовании класса, то есть в большинстве случаев - при первом вызове getInstance().

2. А дает ли это реальный выигрыш, учитывая, что где-нибудь внутри неявно вызванного getClass() будет та же самая синхронизация?

Не знаю, но поскольку Блох один из разработчиков языка - склонен ему верить. Желания ковыряться в исходниках JRE у меня нет :-)
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33808629
Фотография MalkoLinge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
ublic  class  SigletonFactory {
	 private   static  Object object;
	 static  {
		 synchronized  (object) {
			object =  new  Object();

		}
	}	
	 private  SigletonFactory() {	}
	 public  Object getInstance(){
		 return  object;
	}
	

}
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33808644
Фотография MalkoLinge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Syncronized там просто потому что я не очень крутой джавист и не уверен до конца, что статическая секция может быть выполнена несколько раз из разныхпотоков. но уверен что оно там не нужно
WBR,
Malkolinge
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33808655
Фотография MalkoLinge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
окончательній вариант
Код: plaintext
1.
2.
 public   static  Object getInstance(){
		 return  object;
	}
WBR,
Malkolinge
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33808780
BlackWall
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. Синхронизация на неинициализированный член object приводит к NullPointerException.
2. Блох хотел сказать, что пока не вызван метод getInstance() класса FooSingleton, экземпляр этого класса создан не будет. Вызов метода getInstance() приведет к инициализации статических членов класса FooHolder, в частности instance. В результате будет создан экземпляр класса FooSingleton.В принципе, такой вариант эквивалентен варианту 1 первого поста, но порождает еще один класс.
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893237
ska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlLoader Jozicа так?
...


Так нельзя. Читай про Double-checked locking.

Зато так всегда работало.

для C#
или в java
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
 public   class  Single
{
	 private   static  Single instance =  null ;
	 private  Single() {
		// do initiation
	}
	
	 public   static  Single getSingle()
	{
		 if  (instance !=  null )  return  instance;
		 synchronized  (Single. class ) {
			 if  (instance !=  null )  return  instance;
			Single a =  new  Single();
			 synchronized  (a) {
				instance = a;
				 return  instance;
			}
		}
	}
}

есть сомнения ?
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893250
Фотография Кувалдин Роман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ska...есть сомнения?...

Есть
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893255
Фотография Кувалдин Роман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, сразу не вкурил в вышеописанную муть. Да, так наверное будет работать. Но во первых вложенная синхронизация, а во вторых дополнительный объект мне очень не нравятся.

======================
- Я подхожу к клетке с медведем панда...
Видите, какие у него черные круги под глазами?!
Медведь панда как бы всем своим видом говорит нам: "Не бухайте!"
======================
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893263
ska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кувалдин Роман ska...есть сомнения?...

Есть

А зря :-))
В статеечке конечно всё верно, и про volatile в том числе (а были ссылочки на еще одну аналогичную статейку от IBM), но беда этих статей в том что все они говорят как нельзя, но не упоминают (или мало и нежизненно) как можно.

Если Вам удастся показать (хотя бы предположить теоретически) где в моём примере может быть прокол (можно с кодами из разных JIT - x86, x64, pa-risc, power, sparc, ia64) - сниму шляпу.
А вообще идея в том что "synchronized(a)" нельзя обойти или соптимизировать.

Я конечно не беру 1.1.7 Symantec JIT который еще не соблюдал правила по synchronized.

Сергей
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893264
ska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кувалдин РоманИзвиняюсь, сразу не вкурил в вышеописанную муть. Да, так наверное будет работать. Но во первых вложенная синхронизация, а во вторых дополнительный объект мне очень не нравятся.

Так вот как раз без этой вложенной синхронизации (и не по тому же самому обьекту) и нарываемся на проблемы. Черт с ней - ведь это только 1 раз, зато все остальные вызовы пойдут без синхронизации.
...
Рейтинг: 0 / 0
Синхронизация синглетона
    #33893805
funikovyuri
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
unicornmirage
ваш второй вариант верен и обычно называется двойное проверкой. метод новый делать не обязательно, достаточно написать
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 class  MySingleton {
 private   static  MySingleton oneInst =  null ;

 public   static  getInstance() {
   if  (oneInst== null ) {
     synchronized  ( this ) {
           if  (oneInst== null )
             oneInst =  new  MySingleton();
    }

  }

     return  oneInst;
  }
}
вообще решение классическое

насчет вашего третьего примера, он рабочий только инициализация экземпляра синглтона будет происходить не в момент первого обращения, а при загрузке класса.
...
Рейтинг: 0 / 0
25 сообщений из 36, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Синхронизация синглетона
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]