| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Заставить бы Thread возвращать значение |
| Автор: _Y_ 25.1.2007, 21:39 | ||||
| Предистория: В главном потоке вызывается метод. Этот метод делает вычисления и возвращает значение. Выяснилось, что дело медленное и надо показывать прогресс монитор, а для этого вычисления выносить в отдельный Thread. Проблема: После вывода в отдельную Thread возникли сложности с возвратом значения. Попробовал решить так. В классе-наследнике Thread завел переменную valueResult, в которую должен этот самый результат быть записон после окончания работы метода run():
Но встала проблема: как дождаться окончания работы Thread, чтобы эту переменную прочитать? Попробовал сделать так (нарыл что-то подобное в сети и модифицировал):
Подвисает GUI, а если убираю блок try-catch со всем содержимым, то, естественно, значение threadCalculate.valueResult читается до того, как закончился рассчет Эпилог: Понимаю, что изначально надо было делать структуру программы с рассчетом на многопоточность, не бейте. Сейчас переделывать уже будет слишком много. Можно ли как то решить? |
| Автор: s8e8r8g8e 25.1.2007, 22:04 |
| ну да подвисает... вычислитнельный поток замораживается на 100 мсек.. почти сразу за этим основной поток ждёт 100 мсек а не закончится ли вычислительный.. после чего отправляет его опять спать, этак он никогда и не работает кроме как первые 100 мсек а где здесь прогрессбар апдейтится? |
| Автор: _Y_ 25.1.2007, 23:48 | ||
Я и сам вижу что фигня это. Но как сделать не знаю. А прогрессбар апгрейдится внутри метода run(), но это не важно, прогрессбар может быть и indeterminate. Он все равно подвисает вместе с GUI |
| Автор: shimopus 26.1.2007, 00:08 | ||
Предлагаю проверять живость потока, который в свою очередь после того как посчитает значение переменной запишет либо в общедоступный класс, либо дернет метод главного потока.
|
| Автор: Stampede 26.1.2007, 00:32 | ||||
| _Y_, ты пытаешься снаружи опрашивать состояние вычислительного потока, и от этого все твои трудности. На самом деле проблема решается выворачиванием ролей наизнанку: визуальный компонент регистрируется слушателем событий твоего потока, а поток уже по достижении определенных состояний/контрольных точек вызывает методы слушателя. Вот как это может выглядеть на Java. Описываем интерфейс слушателя:
В классе-потоке делаем так:
Надеюсь, понятно, что пример упрощенный, но в целом идея примерно такая. На практике слушателей в общем случае может быть больше одного, поэтому слушателей обычно хранят в списке, а чтобы упростить вызов оповещений, дополнительно объявляют методы типа fireJobStarted(), fireJobDone() и т. д., и в них уже перебирают и в цикле дергают соответствующий метод каждого слушателя. Где-то примерно вот так. |
| Автор: _Y_ 26.1.2007, 12:56 | ||||||
И это пробовал, и с приоритетом потоков играл. Все равно перерисовка GUI подвисает
Это я понимаю. Можно через листенеры делать, а можно, наверное, просто передать потоку ссылку на объект и в конце вычислений просто вызвать метод объекта передав параметр содержащий результат. Проблема-то в том, что этот "правильный" подход потребует серьезной переделки структуры уже работающей программы. Вот и хочется обойтись "малой кровью", т.е. заставить метод запустить поток и обождать результата, но, при этом, не блокировать GUI. |
| Автор: shimopus 26.1.2007, 12:59 |
| а как ты хочешь, чтобы GUI получило результат выполнения операции не ожидая его? Не переделывая ничего не думаю, что что-нибудь получится... |
| Автор: _Y_ 26.1.2007, 19:07 | ||
Да нет. Я просто хотел чтобы GUI перерисовывался не дожидаясь окончания работы метода вызвавшего Thread. Ему результат не нужен. Но, вы все, видимо, правы и Java в этом деле обману не поддается |