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

    +78

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    public class ServiceRunner implements Runnable {
        
        Thread thread = null;
        ServiceUI service;
        public ServiceRunner(ServiceUI service) {       
            this.service = service;
        }
        
        public void start() {
            this.thread = new Thread(this);
            this.thread.start();
        }
    
        public void run() {        
            while (true) {            
                this.service.receiveMessages();            
                try {
    	 	this.thread.sleep(CommonConst.INTERVAL_SERVICE * 1000);
    	    } catch (java.lang.InterruptedException e) {
                    Log.log(Log.ERROR,this,e);
    	}
            this.service.sendMessages();        
            try {
    	       this.thread.sleep(CommonConst.INTERVAL_SERVICE *1000);
    	} catch (java.lang.InterruptedException e) {
                   Log.log(Log.ERROR,this,e);
    	}
        }
        
    }

    очень удивляют предыдущие разрабочтики продукта своими понятиями о потоках в Java

    Запостил: qnikst, 12 Сентября 2010

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

    • ну почти правильно. только я не понял, зачем напоследок засыпать?
      Ответить
      • ничего, что обычно делается (и спроектировано):
        new Thread(Runnable r); а не наоборот? =)

        засыпает, потому, что после выхода его по след разу запускают.
        стоит отдать должное тому, что код работает, но поддерживать его
        и тем более обновлять практически невозможно.
        Ответить
    • > ничего, что обычно делается (и спроектировано):
      new Thread(Runnable r); а не наоборот? =)

      а что в этом не так? По-моему, натурально, что любой обьект может желать запустить свой метод run() в отдельном потоке, при этом ему самому не обязательно быть наследником Thread

      ну нет в яве делегатов, че поделать?
      Ответить
      • 1). если объекту нужно запустить метод некий runnable в отдельном потоке, то он должен сделать Runnable r = new Foo(..);Thread t=new Thread(r);t.start();
        2). если объекту нужно запустить свой runnable, то проблема в дизайне архитектуры кода
        3). при таком подходе из-вне нету доступа к внутреннему Thread поэтому данные умники реализовывали в их Runnable методы isRunning, stop, start, которые по хорошему должны быть у Thread.

        > ну нет в яве делегатов, че поделать?
        дожить до jdk-7 при текущем функционале ;)
        Ответить
        • 1. пускай этим занимается Foo
          2. это проблема отсутствия делегатов: в яве приходится плодить кучу вспомогательных (чаще анонимных) классов, это и потоки (упомянутый Runnable), и слушатели событий и смежные проблемы.
          3. если мы, как в примере, делаем приватное поле типа Thread, то методы isRunning, stop, start по хорошему должны быть именно тут.
          У Thread когда-то были метод stop, но, поскольку он убивал поток мгновенно и жестоко, то вместо пересмотра архитектуры его обьявили вообще deprecated, а управление потоками теперь приходится писать каждый раз заново.

          >дожить до jdk-7 при текущем функционале ;)
          впрочем, лазейки есть. Например, создать аннотацию @Listener(Event) и аннотировать ею методы класса, обработчиком аннотаций прозрачно передавая управление (видел такое в Tapestry5)
          Ответить
          • Runnable - это интерфейс, который должен предоставлять единственный метод run и предполагается, что он или запускается напрямую или в новом потоке. Другое его использование приведёт минимум к непониманию. Поэтому Foo не должен заниматься созданием _единственного_ потока для своего выполнения. Причины:
            1). логичный вызов new Thread(Foo); приведёт к нелогичной работе
            2). нету доступа к объекту потока изне, в результате появляются шедевры вида http://govnokod.ru/4170 про реализацию join(timeout) я уже не пишу.
            3). interrupted Exception при таком подходе остаётся внутри runnable метода, что тоже не логично (в этом куске кода плохо видно).

            Это не значит, что использование Thread внутри Runnable всегда не верно, т.к. есть варианты, где нужно предоставить многопоточность в вызове Run. Данная реализация к таким не относится.

            По поводу 3го пункта, вы точно уверены, что в jdk-6 не появилось новых механизмов управления потоками ;) ?

            а AOP и его реализации это отдельный разговор.
            Ответить
            • > Runnable - это интерфейс, который должен предоставлять единственный метод run и предполагается, что он или запускается напрямую или в новом потоке
              Cовершенно верно, это более общий интерфейс для выполнения какой-то задачи, и не обязательно понимать его как поток (как неплохая иллюстрация: методы invokeLater и invokeAndWait класса SwingUtilities)


              > Другое его использование приведёт минимум к непониманию
              Другое его использование означает непонимание его назначения


              > Поэтому Foo не должен заниматься созданием _единственного_ потока для своего выполнения

              Он должен заниматься логичной обработкой потоков. Он должен создавать поток (или потоки, например, в пуле), стартовать и, если нужно, останавливать поток(потоки) - при этом он не обязан реализовывать Runnable - хотя он может это делать, но тогда накладываются упомянутые ограничения на его использование, и для решения этой проблемы либо документируем соглашения (не создавать более одного потока и т.д.), либо проектируем его интерфейс (набор публичных методов) так, что бы исключить его некорректное использование

              > вы точно уверены, что в jdk-6 не появилось новых механизмов управления потоками ;) ?
              Насколько мне известно, нет. Если я что-то пропустил, буду удивлен ))
              Ответить
              • > Другое его использование означает непонимание его назначения

                что и было продемонстрировано авторами кода. у которых _все_ Runnable содержали в себе Thread. и потом работа с ними из-вне выглядела весьма коряво (ссылка в комментарии выше)

                > Он должен заниматься логичной обработкой потоков...

                не буду спорить, что такой класс имеет право на жизнь и он будет верен. Однако в данному коду он не относится :). Хотя наверное мой код не полон без примера вызова данного метода, где все проблемы видны :)

                насчёт последнего моего комментария отпишусь позже )

                .
                Ответить
                • между прочим, сабжевый подход пропиарен лежащими в нете туториалами, так что удивляться нечему
                  Ответить
              • > Насколько мне известно, нет. Если я что-то пропустил, буду удивлен )
                ну я был не совсем точен.
                изменения пошли с jdk-5, а в 6 были расширены. напр
                изменения реализации групп потоков, Executor[Service], у которого уже есть shutdown, работающий корректно (относительно stop) и т.д. (в т.д. разбираюсь плохо)
                Ответить
            • > а AOP и его реализации это отдельный разговор.
              Если говорить о AOP в полноценном виде, хотя бы тот же AspectJ, который расширяет язык Java (новые ключевые слова и т.д.)

              Сквозное программирование силами Java (с помощью аннотаций, допустим) я не считаю AOP, хотя во многих случаях такие AOP-подобные замашки очень даже удобны
              Например:
              аннотация @Test в JUnit4, позволяющая не придерживаться соглашения имен public void test*()
              Tapestry5 декораторы методов и сервисов (http://tapestry.apache.org/tapestry5/tapestry-ioc/decorator.html)
              Tapestry5 обработчики событий
              (http://tapestry.apache.org/tapestry5/guide/event.html)
              другие аннотации декорирования для логгирования, профайлинга и проч.

              Все это не AOP, а скорее лишь AOP-style
              Ответить
    • Привет, AnimeGovno-_-!
      Ответить

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