- 1
- 2
- 3
synchronized(new Object()){
...
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+100
synchronized(new Object()){
...
}
http://stackoverflow.com/questions/9840959/how-to-judge-which-object-to-be-synchronized-in-java-thread
3.14159265 08.08.2012 14:26 # +2
Писал как-то раз такую синхронизацию в жабе. Сознательно писал.
Ибо нужно было дублировать 2 куска кода - один для несинхронизированных инстансов (завернутый в synchronized), другой для синхронизированных (никуда не завернутый).
Вот так:
roman-kashitsyn 08.08.2012 14:52 # +1
3.14159265 08.08.2012 14:55 # 0
>Collections.synchronizedMap()
Кстати это мысль. Но только заворачивать в него несинхронизированные.
Но как пример подход где можно использовать new Object(), вполне ведь легитимно?
roman-kashitsyn 08.08.2012 15:01 # 0
Вот-вот. Это позволит ускорить код, ведь не будет медленного захвата монитора для никому не нужного обжекта.
new Object() можно, можно ещё Lock явно заюзать. Кода больше, но намерения более явные, и можно добиться условной блокировки.
roman-kashitsyn 08.08.2012 15:13 # 0
Кстати, если блок состоит из нескольких операций над мапой, для конкурентных мап появлятся race condition.
3.14159265 08.08.2012 15:20 # 0
Там в некоторых других местах нужен именно atomic, потому тупо лок на мапе и проверка уже на ConcurrentMap.
> не будет медленного захвата монитора для никому не нужного обжекта.
Лажа в том что для synchronizedMap() тоже создается ненужный объект - обертка. Для GC однохуйственно.
Но теперь на любом вызове метода get, put, contains будет происходть "медленный захват монитора".
Ведь внутри synchronizedMap() те же секции synchronized.
roman-kashitsyn 08.08.2012 15:29 # 0
Если нужно сымитировать именно базовые операции из ConcurrentMap для обычных, я бы обошёлся обёрткой, делающий из обычной мапы ConcurrentMap с внутренней синхронизацией.
Если нужны более сложные операции, то для конкурентных коллекций всё равно потребуется синхронизация, ибо создаёт race condition, хоть и не сломает саму мапу (как может приключиться с обычной мапой).
3.14159265 08.08.2012 15:36 # 0
> потому тупо лок на мапе и проверка уже на ConcurrentMap
Я об этом и написал. Проверка на ConcurrentMap, каст в неё и вызов того же putIfAbsent.
Просто говорю, что
а) от медленного захвата монитора никуда не уйти
б) в случае когда нет готовой синхронизированной обертки, а писать её лень лок по new Object() - самый простой и эффективный подход. По GC выигрыша нет. И там, и там создается объект.
>вот что не совсем понятно: если нужна атомарная операция
Она нужна в другом куске кода.
roman-kashitsyn 08.08.2012 15:44 # 0
Если конкурентная мапа, не лочим временных объектов, да и логика прозрачней.
3.14159265 08.08.2012 16:07 # 0
>>Проверка на ConcurrentMap, каст в неё и вызов того же putIfAbsent.
Но это в другом месте, где нужна неделимость операций.
Это, по-моему, единственный здравый способ. Как-то по-другому написать это трудно.
roman-kashitsyn 08.08.2012 16:21 # +1
synchronizedMap() позволит лишь избежать лишнего захвата монитора для конкурентных мап, но привнесёт несколько захватов для неконкурентных. К тому же, его нельзя использовать, если мапа доступна извне, что скорее всего верно.
3.14159265 08.08.2012 16:27 # 0
А в целом это увиливание от жавопроблем - в т.ч. плохого метода synchronizedMap, который тупо заворачивает всё. В этом плане чистые языки думаю избавят нас от лютого многопоточного майндфака.
roman-kashitsyn 08.08.2012 16:32 # +1
3.14159265 08.08.2012 15:26 # 0
Только внутри sync-mapa
roman-kashitsyn 09.08.2012 10:59 # 0
3.14159265 09.08.2012 15:15 # 0