- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
public sealed class CustomProvider
{
private readonly object _SyncRoot = new object();
public CustomProvider()
{
lock(_SyncRoot)
{
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+141
public sealed class CustomProvider
{
private readonly object _SyncRoot = new object();
public CustomProvider()
{
lock(_SyncRoot)
{
А вообще, если честно, создание экземпляра класса предка (object) всех классов, чтобы произвести захват критической секции - это так печально. Одному мне эта техника кажется удобной, но странной? Нет чтобы создать класс CriticalSection или что-то такое. А они создают объект совсем не связанный с синхронизацией. Не самодокументированно и тут явно какая-то переголова скрывается при создании объекта, по затратам памяти и системных ресурсов, что в каждый объект на уровне имплементации языка приходится по критической секции добавлять.
Кстати, там как реализована эта критическая секция? Хендл этой критической секции фактически системный ресурс и для него по идеи нужно вызывать Dispose, но это не происходит. Тогда почему этих системных хендлов критической секции хватает, хотя ситуация без Dispose похожа на утечку системных ресурсов?
Если кто подумал про lock(this), то это плохо с точки зрения проектирования класса и его последующего использования, поэтому идея с private _SyncRoot - это правильно. Ведь lock(this) (под this в последнем случае имеется данный экземпляр класса), может использоваться и снаружи класса, что может быть пересинхронизацией.
Lennis 24.10.2012 16:20 # +1
A lock statement of the form
lock (x) ...
where x is an expression of a reference-type, is precisely equivalent to
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
"критическая секция" если и реализована, то только в System.Threading.Monitor
HaskellGovno 24.10.2012 16:23 # 0
Ты хочешь сказать, что на самом деле критическая секция глобальна на весь домен/приложение? Не верю. Думаю они в каждый объект напихали по крит секции.
Lennis 24.10.2012 16:38 # +3
В .Net реализована своя синхронизация в потоках, с блокировками и ожиданиями но без использования Win32 primitives
bormand 24.10.2012 16:40 # +4
Суть в том, что каждый тред может уснуть максимум на одном объекте синхронизации, поэтому нет смысла пихать тяжелые ресурсы в каждый объект.
P.S. Ну и да, там тоже вроде бы используют свои примитивы вместо системных, ибо так шустрее.
defecate-plusplus 24.10.2012 16:49 # +2
abatishchev 24.10.2012 16:32 # +2
ничего не понял. чего печально?
создает наиболее легковесный ссылочный тип. в управляемой куче в sync block'е для него указывается ID текущего треда. и данный тред входит в критическую секцию, а обхект становится флагом выхода.
печально вешать лок в конструкторе, это действительно неправильно и говорит о плохом дизайне.
QuickNick 25.10.2012 12:27 # 0
А лок в конструкторе - да, не комильфо.
roman-kashitsyn 25.10.2012 12:47 # +2
странно, ведь массив тоже является объектом
absolut 25.10.2012 13:18 # +1
3.14159265 25.10.2012 14:41 # 0
Конструкторы нужны только чтобы выделять память и инициализировать переменные.
А локи и исключения оставьте для методов, в том числе фабричных.
roman-kashitsyn 25.10.2012 14:44 # +1
Если только язык не поддерживает RAII
3.14159265 25.10.2012 14:45 # +1
absolut 25.10.2012 14:45 # 0
3.14159265 25.10.2012 14:55 # 0
>Что такого критического может случиться на практике
Всё зависит от того зачем хватать лочку. Если просто лок, то ничего.
А если для waitа - чревато исключением и неосвобожденными ресурсами.
http://govnokod.ru/11950#comment156472
А пытаться осбождать ресурсы в конструкторе, при неудачном создании - это верх идиотии.
HaskellGovno 25.10.2012 15:22 # +1
Что? Тут в данном говнокоде лолк только на поле текущего объекта (не статическое поле). То есть в данном случае конструктор может вызываться параллельно в нескольких потоках для разных объектов. Может я чего не понимаю...
3.14159265 25.10.2012 15:23 # 0
Это вообще бессмысленное говно. Я говорю о сколь-нибудь разумном использовании.
roman-kashitsyn 25.10.2012 15:28 # 0
HaskellGovno 25.10.2012 15:30 # 0
По моему она 0вая
roman-kashitsyn 25.10.2012 15:33 # +1
3.14159265 25.10.2012 16:16 # 0
HotSpot следует консервативной рекомендации из JSR-133 Cookbook: «Issue a StoreStore barrier after all stores but before return from any constructor for any class with a final field.»
Другими словами, есть специфичная для хотспота фишка:
// This method (which must be a constructor by the rules of Java)
// wrote a final. The effects of all initializations must be
// committed to memory before any code after the constructor
// publishes the reference to the newly constructor object.
// Rather than wait for the publication, we simply block the
// writes here. Rather than put a barrier on only those writes
// which are required to complete, we force all writes to complete.
То есть, если hotspot обнаруживает в конструкторе запись хотя бы в одно final поле, то он тупо выставляет барьер в конец конструктора и таким образом обеспечивает запись всех полей в конструкторе до записи ссылки на сконструированный объект. Это имеет смысл, чтобы не делать несколько барьеров для нескольких финальных полей.
roman-kashitsyn 25.10.2012 15:53 # +1
roman-kashitsyn 25.10.2012 16:12 # 0
3.14159265 25.10.2012 16:15 # 0
http://habrahabr.ru/post/143390
Сорри за хабр.
/thread
roman-kashitsyn 25.10.2012 16:25 # 0
3.14159265 25.10.2012 16:26 # 0
Это вероятность. Русская рулетка с прицелом в ногу.
roman-kashitsyn 25.10.2012 16:30 # 0
QuickNick 26.10.2012 09:43 # 0
Однажды ухитрились так сделать. В конструктор объекта передали ссылку на ее слушатель, аффтар из конструктора дернул у слушателя метод, а слушатель в этом методе дернул объект.
На большинстве Ява-машин прошло, но на некоторых умирало с NullPointerException.
bormand 25.10.2012 15:39 # 0
Ну да, поэтому я не понимаю нахрена он тут нужен. Разве что защищать недоконструированный объект от вызова других методов....
3.14159265 25.10.2012 15:46 # +2
Весь прикол в том, что объект должен как-то попасть в статик-поле, что несколько тредов могли его прочесть, следовательно должен быть фабричный метод. Без него никак.
HaskellGovno 25.10.2012 15:49 # +4
HaskellGovno 25.10.2012 15:51 # 0
bormand 25.10.2012 15:52 # 0
HaskellGovno 25.10.2012 15:26 # 0
roman-kashitsyn 24.10.2012 16:34 # +5
- неявный монитор есть у каждого объекта, в 99% случаев он не используется
- Clonable, обсуждавшийся недавно
- serialization - это вообще треш-угар-содомия: интерфейс Serialazible не объявляет методов, для кастомизации сериализации нужно объявлять магические приватные методы
- можно изменить System.out, присвоить ему null
etc.
HaskellGovno 24.10.2012 16:41 # 0
Можно ссылку на тред? Разве есть чем заменить Clonable, кроме громоздких клонических фабрик?
roman-kashitsyn 24.10.2012 16:43 # +1
HaskellGovno 24.10.2012 16:44 # 0
Я так понимаю вы про отсутствие кастомной сериализации? А так сериализация нужна. Имхо кастомная не сильно нужна. Думаю, если сильно понадобилась какая-то гиперкастомная, то сериализовать нужно через рефлекшен.
bormand 24.10.2012 16:49 # +2
Вот его описание: http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html.
roman-kashitsyn 24.10.2012 16:51 # +4
Lure Of Chaos 26.10.2012 02:37 # +1