1. C# / Говнокод #13293

    +110

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    public void UpdateCollection()
    {
        object l = new object();
        lock (l)
        {
            // Обновляем коллекцию
        }
    }

    Эксклюзивная блокировка в действии

    Запостил: dormendo, 03 Июля 2013

    Комментарии (46) RSS

    • хотел сказать, что боян, но потом увидел c#
      Ответить
      • > но потом увидел c#
        Что не спасает код от биытия баяном: http://govnokod.ru/11231.
        Ответить
        • Какая разница! Всё это уже было в Симпсонах. http://govnokod.ru/7714
          Ответить
    • самый короткий говнокод

      lock (new object()){ }
      Ответить
      • Мы байтов не экономим. И, согласитесь, мой пример как-то немножко фундаментальнее:)
        Ответить
        • Самый классический и самый фундаментальный вариант:
          lock(this) { ... }

          Ну или так. Чего-уж мелочиться:
          lock(String.Empty) { ... }

          Ну а чтобы веселее дебажилось разбавить всё это красивыми хаками типа:
          lock("") { ... }
          lock(" ".Trim()) { ... }
          Ответить
          • > lock(String.Empty) { ... }
            И программа превращается... программа превращается... в однопоточную.
            Ответить
          • lock(" ".Trim()) { ... } - это уже не говнокод, а какое-то форменное пижонство.
            Ответить
            • Человеческая мысь уже всю галактику облетела побывав на всех планетах. А тут прям так сразу в рамки загонять...
              http://govnokod.ru/62
              Ответить
              • Как из ушата окатило! Стало так гадливо и совестливо на душе!
                Ответить
          • кстати, lock(this) { ... } имеет право на жизнь. именно это имеют ввиду синхронизированные методы в джаве
            Ответить
            • Почитал доки и разъяснения шарпеев насчет lock(this) - все аргументы сводятся к тому, что "кто-нибудь может залочиться об этот объект и мы словим дедлок".

              Но ведь, если объект дальше своих полей и приватных структур данных никуда не лезет, то в lock(this) нет абсолютно ничего страшного.

              А M$, видимо, решило перестраховаться от индусов, и на всякий случай назвало lock(this) порочной практикой, не указывая в каких именно случаях это зло, а когда можно не бояться ;)
              Ответить
              • > "кто-нибудь может залочиться об этот объект и мы словим дедлок".
                ССЗБ лочиться на внешний монитор
                Ответить
              • Интересно другое. Для чего они дали каждому объекту возможность вести себя, как критическая секция и условная переменная одновременно?
                Ответить
                • С явы спиздили, но не до конца ;) В яве это имело смысл из-за синхронайзед методов, а в шарпе, особеннно с их политикой про lock(this), это бессмысленно. Один хрен почти всегда пишут Object locker = new Object(), с тем же успехом можно было бы писать Mutex locker = new Mutext().
                  Ответить
                  • В C# тоже есть синхронизация на уровне методов.
                    Лок(зис) хуже читается, как мне кажется, потому все и создают специальный локер.
                    Ответить
                    • > Лок(зис) хуже читается, как мне кажется, потому все и создают специальный локер.
                      Да ну, нормально он читается :) Локер создают и загоняют в приват чисто ради инкапсуляции, чтобы кроме методов текущего объекта никому не приходила в голову мысль об него лочиться.
                      Ответить
                      • Главное в доках потом написать

                        Thread Safety: all methods of this class are thread safe and it's instances must not be locked explicitly.
                        Ответить
                        • Ну если это написать(искренне надеясь, что доку кто-то читает), то можно и lock(this) юзать.
                          Ответить
                          • Те, кто лочат объекты, не проверяя потокобезопасность класса - сами себе злые питушки.
                            Так и рождается synchronized(concurrentMap)
                            Ответить
                            • > synchronized(concurrentMap)
                              Можно было даже отдельным говнокодом. Самая соль.
                              Ответить
                              • В .NET появились конкурентные коллекции.
                                1. Лочатся они эксклюзивно. Всегда.
                                2. С ними порой такие перожки получаются, любо-дорого посмотреть.
                                Ответить
                                • > В .NET появились конкурентные коллекции.
                                  LockFree-коллекции есть? Или LockUnlucky-коллекции? Или LockSeldomForOwner-коллекции?

                                  > перожки получаются, любо-дорого посмотреть.
                                  Какие пирожки?
                                  Ответить
                                  • Программисты иногда начинают считать, что достаточно использовать синхронизированные коллекции, чтобы два последовательных обращения к ним (сначала на чтение, потом на запись) без внешней синхронизации обеспеспечивали устойчивое поведение. И далеко не с первого раза получается объяснить.
                                    Ответить
                                    • Очень интересно, можете развить мысль, чем же синхронизированные коллекции не комильфо?
                                      Ответить
                                      • Тут нет такого, чтобы комильфо или нет. Есть реальная проблема. Я уже развил кое-какую мысль по этому поводу. Кодеры порой считают их панацеей, не требующей внешней синхронизации. Например, есть кеш, оборачивающий реальные данные. Кеш на сервере, потоков много. Программист без капли сомнения пишет несколько последовательных инструкций к таким коллекциям без внешней синхронизации. Когда ему указываешь, что вот тут - источник ошибок и исключений, программист может долго возмущаться в духе "но конкурентные коллекции специально созданы для решения проблем многопоточности".
                                        Ответить
                                        • > есть кеш, оборачивающий реальные данные

                                          С кэшем обычно ещё интереснее: данные могут храниться в нескольких структурах одновременно (например, хэш-табличка и LRU-очередь), и синхронизировать нужно сразу несколько объектов.
                                          Ответить
                                          • В нашем случае вытеснение не требуется. Все данные легко умещаются в 3Мб, даже если пользователей несколько тысяч.
                                            Ответить
              • Да, именно защита от индусов - обьект для лока должен быть недосигаем нигде, кроме методов этого обьекта - не всякий пожарный.

                Собственно сами ребята из MS говорят
                "Как правило, рекомендуется избегать блокировки типа public или экземпляров, которыми код не управляет. Распространенные конструкторы lock (this), lock (typeof (MyType)) и lock ("myLock") не соблюдают это правило.
                lock (this) может привести к проблеме, если к экземпляру допускается открытый доступ.
                lock (typeof (MyType)) может привести к проблеме, если к MyType допускается открытый доступ.
                lock("myLock") может привести к проблеме, поскольку любой код в процессе, используя ту же строку, будет совместно использовать ту же блокировку."

                Да не воздай доступа к блокировке своей!
                Ответить
                • > Распространенные конструкторы lock (this), lock (typeof (MyType)) и lock ("myLock")
                  Блин, мне страшно юзать софт на фреймворке, если там этот лок по строке распространен.

                  P.S. Разве lock(ченить) это конструктор? Это же специальный оператор.
                  P.P.S. Открыл инглиш версию. construct (конструкция) а не constructor там написано. Переводчик у них как всегда ёбнутый на голову ;)

                  lock(null)
                  Ответить
                  • Залочить(никак)
                    ;)
                    А чем то подход MS очень даже хорош - считай всех тупым быдлом и не будешь разочарован )

                    А переводят те же пользователи. Чем сложнее статья - тем хреновее переведена. Инфа 100%.
                    Ответить
                    • > А переводят те же пользователи.
                      О, а я думал, что там нечто типа промпта старается...
                      Ответить
                      • Изначально вроде автоматика переводит, но когда наводишь на текст вылетает волшебное"предложить более удачный вариант перевода", и через него юзеры "обтачивают" перевод. А так как гуру обычно на английском читают, то допереводят прогеры самого среднего звена со всеми вытикающими
                        Ответить
                        • >Допереводят юзеры, которым это в хуй не упало.
                          Починил.
                          Ответить
                • Если программист - мудак, и верит во всепобеждающую силу сборщика мусора, LINQ to SQL или другой подобной приблуды, ему не поможет ничто.
                  Ответить
    • Смысл данного говнокода в том, что блокировка обеспечивает эксклюзивный доступ к критической секции, если весь код, который может ее исполнить, лочится одним и тем же локом. А тут обьект лока создается при каждом вызове функции. Так-то!

      Хуевый из меня кеп, да.
      Ответить
      • Удивительно, сколь много с Вами согласившихся!
        Ответить
      • Кеп, дополню твою мысль и скажу что если убрать
        object l = new object();
        lock (l){}
        то ничего не изменится
        Ответить
        • Изменится ;)
          Программа начнет работать чуточку быстрее из-за меньшего давления на кучу и экономии нескольких инструкций на lock/unlock.
          Ответить
          • Ну вообще да, инструкция явно не на один ЭШ. Можно извернуться и так написать, что lock будет узким местом)

            И вообще - не позорьте меня перед Кепом!)))
            Ответить
            • > Можно извернуться и так написать, что lock будет узким местом
              Это надо этот лок дрочить несколькими тредами. Успешный лок без коллизий практически бесплатен.
              Ответить

    Добавить комментарий