|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Всем привет, есть необходимость создать потокобезопасный синглтон, чтобы можно было менять в нем данные из разных потоков. К сожалению в документации не нашел 100% ответ будет ли он безопасный в зависимости от разных условий инициализаций. Попытался сам проверить потокобезопасность следующими тестами. Код: c# 1. 2. 3. 4. 5. 6.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
Вопрос- позволяет ли данные второго теста (Kernel.Bind<Lazy<DataStore>>().ToConstant(new Lazy<DataStore>( () => new DataStore() )).InThreadScope();) утверждать, что синглтон потокобезопасен? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 16:38 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_sub, Объект безопасный, если все его поля до пятого колена безопасны. Вывод, бери безопасные коллекции.....типа ConcurrenrDictionary. Но у меня иногда и это глючит без блокировки. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 17:22 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Под потокобезопасностью синглтона подразумевается не потокобезопасность его методов или состояния, а потокобезопасное создание экземпляра синглтона ( см. у Скита ). То, что некий класс является [потокобезопасным] синглтоном, и то, что его свойства/методы потокобезопасны - вещи ортогональные. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 17:51 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Ну и синглетон не имеет отношения к сабжу. Синглетон - экземпляры, а ThreadSafe - доступ. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 17:53 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, Спс за ссылку. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 17:55 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_sub, У меня список для потокового доступа просто находится рядом с главной формой ГУИ. И не надо синглетона). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 17:59 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныПод потокобезопасностью синглтона подразумевается не потокобезопасность его методов или состояния, а потокобезопасное создание экземпляра синглтона ( см. у Скита ). То, что некий класс является [потокобезопасным] синглтоном, и то, что его свойства/методы потокобезопасны - вещи ортогональные. Я не спец в ninject, но, думаю, что как и всякий приличный DI-контейнер, он должен обеспечить безопасное создание синглетона из коробки без всяких дополнительных телодвижений. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 19:23 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Ninject в глаза не видел, так что могу наврать. InThreadScope по идее указывает на то, что на каждый поток будет создан свой экземпляр "синглтона", т.е. сам класс объекта может быть и не потокобезопасным и у каждого потока будет свой DataStore и своё значение свойства Name. Если делать Lazy прям синглтон, что один для всех, то: Класс Lazy, согласно msdn является потокобезопасным, но вот сам DataStore таким не является. как-то так получается: Код: c# 1. 2. 3.
В общем, Lazy ничего не даёт и не нужен тут. Ninject и сам по сути роль Lazy выполняет. DataStore конкретно в данном случае синхронизировать не нужно, т.к. на каждый поток будет свой экземпляр. Если прописать InSingletonScope(), тогда и DataStore нужно thread-safe'ить. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 19:26 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Pu4koff, на lazy не стоит заострать внимание-он просто делает отложенную инициализация, на потокобезопасность никак не влияет. Стандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам. Еще метанит приводит такой пример потокобезопасного синглтона без лока Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
только не очень понятно как Guid сделает его потокобезопасным. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:27 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_subСтандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам. Еще метанит приводит такой пример потокобезопасного синглтона без лока Я вообще не понимаю - кому в наш век повсеместного DI может понадобиться писать свой синглтон. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:36 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_sub, под потокобезопасным синглтоном понимают то, что при получении объекта из разных потоков будет получен один и тот же объект. Это не значит что сам объект потокобезопасен, а только то, что можно одновременно вызвать метод: Код: c# 1.
и получить один и тот же объект. В примере guid используется чисто для проверки. Типа можно запустить кучу потоков, в них выполнить: Код: c# 1.
и получить одну и ту же строку. Потокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами. При работе с такими "потокобезопасными" синглтонами нужно просто помнить и о потокобезопасности самого объекта, тут обезопасили только метод Singleton.GetInstance() и не более того. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:37 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_subСтандартно советуют делать синглтон с lock для поткобезопасности, но он расточителен по ресурсам. Даблчек-лок практически не даст оверхеда, разве что кроме первого вызова. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:38 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
string потокобезопасен поэтому твоя обертка на над ним тоже потокобезопасна. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:39 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
fkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:39 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Pu4kofffkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :)+1 ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:46 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Pu4kofffkthat, я вообще думал, что синглтоны уже несколько лет как перевели в антипаттерны :) Да херь все это от Башни Слонячей Кости. Точно так же можно сказать, что конструктор это антипаттерн, а использовать надо только фабрики, а еще лучше абстрактные фабрики. К тому же я уже вообще и забыл, как объекты руками создавать - у нас везде когда что-то надо, то добавляешь в конструктор, а IoC сам туда всунет что нужно - синглтон там или не синглтон, или даже вообще какой-то обьект в другом процессе - меня, как его потребителя, это вообще не парит - это забота того, кто контейнер конфигурирует и самого контейнера. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:54 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Код: c# 1. 2. 3. 4.
то есть если я предполагаю, что FakeList будет редактироваться из разных потоков, и я не хочу, чтобы какие- либо изменения пропали мне нужно искать Thread-Safe ObservableCollection<T> обертку? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 20:54 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_subто есть если я предполагаю, что FakeList будет редактироваться из разных потоков, и я не хочу, чтобы какие- либо изменения пропали мне нужно искать Thread-Safe ObservableCollection<T> обертку? Да. Использовать ReaderWriterLock или ReaderWriterLockSlim. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 21:03 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_sub, По хорошему, надо не допускать редактирования ресурса из разных потоков. Нарезать куски работы для каждого потока - вот такой хайп параллельности. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 21:06 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
fkthat, это всё из-за модников-неучей. Сначала лепили статические классы. Потом начали задумываться о времени жизни объектов, о реализации интерфейсов и т.д. и т.п. и ломанулись использовать синглтон, типа это такая серебряная пуля, всем и всегда поможет. Статикам табу, синглтонам - милости просим. Потом опять голову включили и оказалось, что у синглтонов тоже не всё круто. Теперь им табу, а на коне всякие DI и сотоварищи. По факту просто всему своё место. И статические классы норм и синглтоны и т.д. и т.п. Законодателям моды проще было сказать, что синглтоны не комильфо пользовать. vb_sub, не забываем еще и про потокобезопасность FakeClass, если возможна работа с одним объектом коллекции из разных потоков. Если разные потоки могут забрать один и тот же элемент коллекции и как-то его менять, тогда его внутренности тоже нужно защищать. И всё равно там не всё так однозначно будет. Типа напишете DataStore.Name = DataStore.Name + DataStore.Name по отдельности всё безопасно, а в сумме одна большая беда. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 21:58 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
vb_subPu4koff, на lazy не стоит заострать внимание-он просто делает отложенную инициализация, на потокобезопасность никак не влияет. вообще то в Lazy<T> реализована потоколбезопасность, по этому из 2 потоков получить 2 разных ленивых объекта не получится. https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs,8b99c1f377873554, там даже в конструкторе есть параметр ThreadSafe ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 22:44 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Pu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами. Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2018, 23:29 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныPu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами. Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>). Кури спеки. Инициализация статического поля компилятором помещается либо в начало существующего статического конструктора, либо, при отсутствии оного, в сгенерированный. Статический конструктор всегда вызывается в потокобезопасной манере - хоть сколько потоков одновременно обратятся к классу, статический конструктор вызовется только один раз, одним потоком и до выполнения любого кода того же класса. Т.ч. реализовывать синглтон через статическое поле это и есть самый эффективный и простой метод - а всё это дрочево с локами, двойной проверкой и проч. - это только чтобы джуниоров на интервью погномить. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2018, 00:07 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
Сон Веры ПавловныPu4koffПотокобезопасность синглтона там реализуется за счёт статического readonly члена класса со всеми вытекающими плюсами и минусами. Неправильно. Статическое readonly поле - всего лишь для хранения экземпляра, само по себе оно ничего не гарантирует, потокобезопасность там реализуется либо за счет вручную прописанных локов, либо за счет манпуляций с IL-флагом beforefieldinit , либо за счет обеспечивающих потокобезопасность классов FCL (Lazy<T>). так в этом и смысл синглтона, что там ровно один экземпляр. Ровно это и даёт статический член класса с инициализацией. такой синглтон не потокобезопасный: Код: c# 1. 2. 3. 4. 5. 6.
если if обернуть в тот же lock, тогда уже типа будет потокобезопасный синглтон, но это не значит, что стал потокобезопасным возвращенный объект типа А. при таком варианте: Код: c# 1.
невозможна же ситуация, что instance в разное время будет ссылаться на разные объекты или что инициализатор new Singleton() отработает несколько раз для разных потоков? А большего от синглтона и его потокобезопасности и не нужно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2018, 00:15 |
|
Потокобезопасный singleton от Ninject
|
|||
---|---|---|---|
#18+
fkthatКури спеки. Инициализация статического поля компилятором помещается либо в начало существующего статического конструктора, либо, при отсутствии оного, в сгенерированный. Статический конструктор всегда вызывается в потокобезопасной манере - хоть сколько потоков одновременно обратятся к классу, статический конструктор вызовется только один раз, одним потоком и до выполнения любого кода того же класса. Т.ч. реализовывать синглтон через статическое поле это и есть самый эффективный и простой метод - а всё это дрочево с локами, двойной проверкой и проч. - это только чтобы джуниоров на интервью погномить. Кури человеческую реализацию паттерна. Инициализация поля экземпляра синглтона в статик-конструкторе в общем случае делает его не ленивым - см. выше про флаг beforefieldinit. Поскольку мало кто представляет все нюансы этого флага, то для перестраховки выносят инициализацию инстанса из статического инициализатора типа, и оборачивают в локи - так добиваются и ленивости, и потокобезопасности. Кто представляет - использует пустой статик-конструктор, и тоже не инициализирует инстанс в статическом конструкторе (т.к. мым можем в коде обратиться к константе класса синглтона, или к статик-методу, не связанному с инстансом - а у нас всё равно будет создан экземпляр). ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2018, 08:13 |
|
|
start [/forum/topic.php?fid=20&fpage=34&tid=1399520]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
49ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 177ms |
0 / 0 |