- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 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
Lure Of Chaos 12.09.2010 18:33 # 0
qnikst 12.09.2010 18:42 # 0
new Thread(Runnable r); а не наоборот? =)
засыпает, потому, что после выхода его по след разу запускают.
стоит отдать должное тому, что код работает, но поддерживать его
и тем более обновлять практически невозможно.
Lure Of Chaos 12.09.2010 19:43 # 0
new Thread(Runnable r); а не наоборот? =)
а что в этом не так? По-моему, натурально, что любой обьект может желать запустить свой метод run() в отдельном потоке, при этом ему самому не обязательно быть наследником Thread
ну нет в яве делегатов, че поделать?
qnikst 12.09.2010 20:10 # 0
2). если объекту нужно запустить свой runnable, то проблема в дизайне архитектуры кода
3). при таком подходе из-вне нету доступа к внутреннему Thread поэтому данные умники реализовывали в их Runnable методы isRunning, stop, start, которые по хорошему должны быть у Thread.
> ну нет в яве делегатов, че поделать?
дожить до jdk-7 при текущем функционале ;)
Lure Of Chaos 12.09.2010 20:38 # +1
2. это проблема отсутствия делегатов: в яве приходится плодить кучу вспомогательных (чаще анонимных) классов, это и потоки (упомянутый Runnable), и слушатели событий и смежные проблемы.
3. если мы, как в примере, делаем приватное поле типа Thread, то методы isRunning, stop, start по хорошему должны быть именно тут.
У Thread когда-то были метод stop, но, поскольку он убивал поток мгновенно и жестоко, то вместо пересмотра архитектуры его обьявили вообще deprecated, а управление потоками теперь приходится писать каждый раз заново.
>дожить до jdk-7 при текущем функционале ;)
впрочем, лазейки есть. Например, создать аннотацию @Listener(Event) и аннотировать ею методы класса, обработчиком аннотаций прозрачно передавая управление (видел такое в Tapestry5)
qnikst 13.09.2010 12:18 # 0
1). логичный вызов new Thread(Foo); приведёт к нелогичной работе
2). нету доступа к объекту потока изне, в результате появляются шедевры вида http://govnokod.ru/4170 про реализацию join(timeout) я уже не пишу.
3). interrupted Exception при таком подходе остаётся внутри runnable метода, что тоже не логично (в этом куске кода плохо видно).
Это не значит, что использование Thread внутри Runnable всегда не верно, т.к. есть варианты, где нужно предоставить многопоточность в вызове Run. Данная реализация к таким не относится.
По поводу 3го пункта, вы точно уверены, что в jdk-6 не появилось новых механизмов управления потоками ;) ?
а AOP и его реализации это отдельный разговор.
Lure Of Chaos 13.09.2010 14:11 # 0
Cовершенно верно, это более общий интерфейс для выполнения какой-то задачи, и не обязательно понимать его как поток (как неплохая иллюстрация: методы invokeLater и invokeAndWait класса SwingUtilities)
> Другое его использование приведёт минимум к непониманию
Другое его использование означает непонимание его назначения
> Поэтому Foo не должен заниматься созданием _единственного_ потока для своего выполнения
Он должен заниматься логичной обработкой потоков. Он должен создавать поток (или потоки, например, в пуле), стартовать и, если нужно, останавливать поток(потоки) - при этом он не обязан реализовывать Runnable - хотя он может это делать, но тогда накладываются упомянутые ограничения на его использование, и для решения этой проблемы либо документируем соглашения (не создавать более одного потока и т.д.), либо проектируем его интерфейс (набор публичных методов) так, что бы исключить его некорректное использование
> вы точно уверены, что в jdk-6 не появилось новых механизмов управления потоками ;) ?
Насколько мне известно, нет. Если я что-то пропустил, буду удивлен ))
qnikst 13.09.2010 16:47 # 0
что и было продемонстрировано авторами кода. у которых _все_ Runnable содержали в себе Thread. и потом работа с ними из-вне выглядела весьма коряво (ссылка в комментарии выше)
> Он должен заниматься логичной обработкой потоков...
не буду спорить, что такой класс имеет право на жизнь и он будет верен. Однако в данному коду он не относится :). Хотя наверное мой код не полон без примера вызова данного метода, где все проблемы видны :)
насчёт последнего моего комментария отпишусь позже )
.
Lure Of Chaos 13.09.2010 17:09 # 0
qnikst 13.09.2010 19:26 # 0
ну я был не совсем точен.
изменения пошли с jdk-5, а в 6 были расширены. напр
изменения реализации групп потоков, Executor[Service], у которого уже есть shutdown, работающий корректно (относительно stop) и т.д. (в т.д. разбираюсь плохо)
Lure Of Chaos 13.09.2010 19:29 # 0
вот именно
Lure Of Chaos 13.09.2010 14:25 # 0
Если говорить о 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-_- 19.10.2011 07:33 # −1
3.14159265 19.10.2011 13:31 # +1
AnimeGovno-_- 19.10.2011 13:48 # −1
bugmenot 19.10.2011 14:12 # 0