Как стать автором
Обновить

Комментарии 33

НЛО прилетело и опубликовало эту надпись здесь
в статье приведено множество кривых способов реализации, кроме классического c synchronized методами. Выучите этот способ и будет вам счастье. Ну не всегда эффективно, зато железобетонно надежно. А все зло от оптимизаций. Оптимизировать надо алгоритмы, а экономить на спичках, пытаясь лишний раз не вызывать synchronized, все равно бесполезно. Баг 143074 тоже вызван попыткой написать все суперэффективно.
НЛО прилетело и опубликовало эту надпись здесь
Все верно. Краткость сестра таланта. Была бы возможность, дал бы вам свой голос.
Мне надо было написать «все зло от низкоуровневых оптимизаций».

Composability к теме комментария вообще не имеет отношения. Все приведенные по ссылке варианты точно также non-composable.

Насчет сто раз — сто раз по сравнению с чем? с несинхронизованным доступом к памяти? Так бесплатного ничего не бывает. Если synchronized берет 100 нс, и исполняется 100 тысяч раз в секунду, то удаление synchronized повысит общую производительность на 1%. Но чтобы сохранить корректность, придется изрядно повозиться, и эта корректность рассыпется с приходом очередного Васи Пупкина. И это при том, что 100 тысяч — это экстремальный случай. В 99% случаев это означает просто плохой алгоритм.

Так что объяснения ваши я не воспринял.
НЛО прилетело и опубликовало эту надпись здесь
На volatile или атомик тратится 1 нс, на synchronized 50 нс. И что? Это играет роль, если геттер вызывается миллионы раз в секунду. В такой ситуации вы что предпочтете — ускорять геттер или сесть и подумать, как сократить число обращений к общим данным?
НЛО прилетело и опубликовало эту надпись здесь
10.000 нс? Не верится. Приведите тест. Неужели мой тест, дающий 50 нс — не contended?
НЛО прилетело и опубликовало эту надпись здесь
Подождем пока TheShade провалидирует тест. :)
А пока просто немного посчитаем в уме:
50 нс + 3 GHz (вряд ли сильно больше) => 150 тактов оценка сверху.
Если synchronized действительно contended, то никаких think-lock'ов и прочего, никакой adaptive spinning уже не поможет. Значит fat, а это поход в ядро. Сделать ядерный лок за 150 тактов — не верю.
TheShade успел раньше ;)
Но все таки от ответа, что не так он уклонился :)

Делаю предположение, что срабатывает dead code elimination, sum и sum1 нигде не используются, да и sum1 вообще не sum, а просто результат последнего get.
НЛО прилетело и опубликовало эту надпись здесь
Да, там вкралось лишнее деление на 10, так что 7 и 500 нс (2*1.6 GHz ).
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Всегда так называлось. Высокоуровневая оптимизация — это, например, замена O(N) на O(ln(N) ).
Очевидно же что с реалиями многопоточности использование этой самой многопоточности больше не является низкоуровневой оптимизацией. Именно поэтому и придумываются особенные алгоритмы оптимизированные под эту самую многопоточность. И понятно что ассимптотика относительно размера входных данных не меняется. Просто величина кол-ва процессоров тоже может быть параметром времени алгоритма.
> Мне надо было написать «все зло от низкоуровневых оптимизаций».

Так для того и сделан j.u.c.ConcurrentHashMap например, чтобы люди не занимались низкоуровневыми оптимизациями, а получили уже готовый и хорошо скалируемый lock-free алгоритм.

А велосипеды изобретать не стоит.
>уже готовый и хорошо скалируемый lock-free алгоритм.

Традиционное заблуждение. ConcurrentHashMap совсем не лок-фрии, а самая что ни на есть обычная synchronized, параметр «cuncrrency level» в конструкторе не смущал? А идея в ConcurrentHashMap очень простоая — распилим хеш-таблицу на N synchronized хеш-таблиц, определяя необходимую мапа по ключу как key.hashCode() % N. Тоесть если будет борьба за схожие элементы в таблице — производительность у нее выродится в производительность synchronized таблицы.
НЛО прилетело и опубликовало эту надпись здесь
Да, действительно, погорячился (геттер, действительно, без блокировок). Спасибо что попроавили :)
Прикольные баги в j.u.c.* повышают относительную ценность самопальных велосипедов…
«Прикольные баги» и «самопальные велосипеды» — это, если что, цитаты из отвечаемого коммента. В статье по ссылке из него баги в j.u.c.* несколько раз упоминаются. Что поделать, если в классической красоте из j.u.c.* критические баги обещают исправить очень «завтра», а работающая функциональность требуется «уже вчера»…
Спасибо, интересная статья, занёс в закладки.
Хороший справочный пост. В многопоточности не силен к сожалению, потому постарался внимательно прочитать статью, но тема такая, что думаю не раз еще перечитаю — добавил в избранное. Спасибо.
ReentrantReadWriteLock — Очень часто используется в многопоточных сервисах и кешах, показывая очень хороший прирост производительности по сравнению с блоками synchronized

Небольшая неточность, не везде и не всегда он выигрывает у synchronized, см. статью.
> просто берешь и пишешь, благо ничего суперсложного в многопоточности нет.

ORLY?
До сих пор с теплотой вспоминаю как нам в инсте один единственный раз на лекции рассказали про многопоточность в яве. Дескать вот там Runnable, всё, закончили с многопоточностью, пошли дальше))
> Doug Lea (Даг Ли), профессора Oswego (Осуиго) университета штата Нью Йорк

Представляю, как его студентам: кто-то говорит — «а вот у нас профессор на лекции про Яву рассказывал», а они в ответ — «а у нас профессор Яву как раз развивает» )
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.