1. Java / Говнокод #16590

    +76

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    private Boolean active = false;
    ...
    synchronized (active) {
    ...
    }

    Чудо синхронизации. Блокируется раз и навсегда.

    Запостил: borka, 25 Августа 2014

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

    • А в чём отличие явовского synchronized от .net' овского lock?
      Судя по мануалу:
      http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
      Особой разницы нет.
      Ответить
    • А почему раз и навсегда? (хлоп-хлоп глазами)
      Ответить
      • Потому что под synchronized долгоживущий код, а Boolean.FALSE / Boolean.TRUE в единственном экземпляре на всю JVM.
        Должно быть что-то типа synchronized(this).
        Ответить
        • >synchronized(this)
          Тоже считается плохим тоном - если совсем по-правильному.
          Имеем утечку приватного мьютекса, пользователь может синхронизироваться на данном объекте и сломать абстракцию. Потому в тех же коллекциях this не используют.
          Я бы предпочёл private final AtomicBoolean - если код многопоточный вероятно это лучше чем мутабельная ссылка, на которой синхронизируются.
          или private Boolean active = new Boolean(false);
          Ответить
          • Прятать/не прятать - дело хозяйское. Вообще неплохо иметь дополнительный конструктор в который передается внешний объект синхронизации. Например можно заводить один лок на несколько объектов и не боятся дедлока при различных путях вызовов между этими объектами.
            Ответить
            • >Вообще неплохо иметь дополнительный конструктор в который передается внешний объект синхронизации.
              >Например можно заводить один лок на несколько объектов и не боятся дедлока
              Согласен. Вот в каллекциях засинхронизировали всё внутри, а итераторы забыли.
              А конструкторы полезные с этим самым мьютексом package-private.
              Ответить
              • А в чем сакральный смысл делать две коллекции с одним мутексом?

                Дедлока тут и так не может быть, ибо мутекс захвачен только на время работы метода. И ни один метод, емнип, управление из-под лока не отдает (ну разве что в какой-нибудь equals).

                Атомарности это не добавит, ибо мутекс захватывается только на время работы метода коллекции. И если я вызову джва метода - между ними всё равно будет дырка.

                Если же я, пытаясь избавиться от этой дырки, захвачу мутекс сам, заранее - то какой смысл захватывать его еще раз внутри методов коллекции? Тут самых обычных коллекций хватит, ибо внешняя синхронизация.
                Ответить
                • >А в чем сакральный смысл делать две коллекции с одним мутексом?
                  Мапа - раз.
                  Её view KeySet - два.
                  Её view valueCollection - три.
                  Итераторы на keys, values, entries.

                  Видишь ли view мапы может менять её наравне с обычными методами, и каждый из них необходимо заблочить одним и тем же мьютексом.
                  Даже в итераторе есть мутирующий remove (что лично по-моим соображениям - ошибка в проектировании, обычный итератор должен быть ronly, т.к. 95% юзкейсов - обычный обход).
                  Ответить
                  • > view мапы может менять её наравне с обычными методами, и каждый из них необходимо заблочить одним и тем же мьютексом.
                    Так эти вьюхи же получают этот мутекс в конструкторе, когда мапа их запиливает. Разве нет?

                    > итераторе
                    Кстати, а как работает итератор у этих недосинхронизированных коллекциях?

                    P.S. Нашел - никак не работает. Нужно самому лочиться об мапу :( Поэтому итератор тут не навредит - его за мутексом юзать вообще нельзя.

                    P.P.S. И я так и не понял, от чего спасёт возможность передачи внешнего мутекса недосинхронизированным коллекциям.
                    Ответить
                    • >>Так эти вьюхи же получают этот мутекс в конструкторе, когда мапа их запиливает. Разве нет?
                      Вьюхи это ответ на вопрос:
                      >А в чем сакральный смысл делать две коллекции с одним мутексом?
                      Ответить
                      • А, понял, спасибо. Но с другой стороны - это же несколько проекций одной коллекции, а не несколько независимых коллекций с одним мутексом.

                        А для независимых особого смысла в передаче мутекса я не вижу.
                        Ответить
                  • > обычный итератор должен быть ronly, т.к. 95% юзкейсов - обычный обход
                    Ну вот, кстати, в тех же крестах правильно сделали - итератор не может удалять элементы. Зато можно передать этот итератор соотв. методу коллекции, и он выпилит элемент (или несколько).
                    Ответить
        • Так и в чем вечность блока? когда то же он выпадет из лока. Ну и еще это своеобразный мьютекс для тех, кто неосилил
          Ответить
    • "Пофиксил"

      synchronized(new Object()){
      ...
      }
      Ответить
    • А-ах, как умно...
      Автор, утопись в отхожем мисце!
      Ответить

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