![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| _Y_ |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 5 Всего: 34 |
Предистория: В главном потоке вызывается метод. Этот метод делает вычисления и возвращает значение. Выяснилось, что дело медленное и надо показывать прогресс монитор, а для этого вычисления выносить в отдельный Thread.
Проблема: После вывода в отдельную Thread возникли сложности с возвратом значения. Попробовал решить так. В классе-наследнике Thread завел переменную valueResult, в которую должен этот самый результат быть записон после окончания работы метода run():
Но встала проблема: как дождаться окончания работы Thread, чтобы эту переменную прочитать? Попробовал сделать так (нарыл что-то подобное в сети и модифицировал):
Подвисает GUI, а если убираю блок try-catch со всем содержимым, то, естественно, значение threadCalculate.valueResult читается до того, как закончился рассчет Эпилог: Понимаю, что изначально надо было делать структуру программы с рассчетом на многопоточность, не бейте. Сейчас переделывать уже будет слишком много. Можно ли как то решить? -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
||||
|
|||||
| s8e8r8g8e |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 41 Регистрация: 12.5.2006 Репутация: 1 Всего: 1 |
ну да подвисает...
вычислитнельный поток замораживается на 100 мсек.. почти сразу за этим основной поток ждёт 100 мсек а не закончится ли вычислительный.. после чего отправляет его опять спать, этак он никогда и не работает кроме как первые 100 мсек а где здесь прогрессбар апдейтится? |
|||
|
||||
| _Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 5 Всего: 34 |
Я и сам вижу что фигня это. Но как сделать не знаю. А прогрессбар апгрейдится внутри метода run(), но это не важно, прогрессбар может быть и indeterminate. Он все равно подвисает вместе с GUI -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
| shimopus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 103 Регистрация: 25.8.2006 Репутация: 1 Всего: 1 |
Предлагаю проверять живость потока, который в свою очередь после того как посчитает значение переменной запишет либо в общедоступный класс, либо дернет метод главного потока.
|
|||
|
||||
| Stampede |
|
||||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
_Y_, ты пытаешься снаружи опрашивать состояние вычислительного потока, и от этого все твои трудности. На самом деле проблема решается выворачиванием ролей наизнанку: визуальный компонент регистрируется слушателем событий твоего потока, а поток уже по достижении определенных состояний/контрольных точек вызывает методы слушателя. Вот как это может выглядеть на Java.
Описываем интерфейс слушателя:
В классе-потоке делаем так:
Надеюсь, понятно, что пример упрощенный, но в целом идея примерно такая. На практике слушателей в общем случае может быть больше одного, поэтому слушателей обычно хранят в списке, а чтобы упростить вызов оповещений, дополнительно объявляют методы типа fireJobStarted(), fireJobDone() и т. д., и в них уже перебирают и в цикле дергают соответствующий метод каждого слушателя. Где-то примерно вот так. |
||||
|
|||||
| _Y_ |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 5 Всего: 34 |
И это пробовал, и с приоритетом потоков играл. Все равно перерисовка GUI подвисает
Это я понимаю. Можно через листенеры делать, а можно, наверное, просто передать потоку ссылку на объект и в конце вычислений просто вызвать метод объекта передав параметр содержащий результат. Проблема-то в том, что этот "правильный" подход потребует серьезной переделки структуры уже работающей программы. Вот и хочется обойтись "малой кровью", т.е. заставить метод запустить поток и обождать результата, но, при этом, не блокировать GUI. -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
||||||
|
|||||||
| shimopus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 103 Регистрация: 25.8.2006 Репутация: 1 Всего: 1 |
а как ты хочешь, чтобы GUI получило результат выполнения операции не ожидая его? Не переделывая ничего не думаю, что что-нибудь получится...
|
|||
|
||||
| _Y_ |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1651 Регистрация: 27.11.2006 Репутация: 5 Всего: 34 |
Да нет. Я просто хотел чтобы GUI перерисовывался не дожидаясь окончания работы метода вызвавшего Thread. Ему результат не нужен. Но, вы все, видимо, правы и Java в этом деле обману не поддается Это сообщение отредактировал(а) _Y_ - 26.1.2007, 19:07 -------------------- Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:) |
|||
|
||||
| powerOn |
|
|||
![]() software saboteur ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4367 Регистрация: 7.10.2005 Репутация: 47 Всего: 159 |
Нужно вынести логику в отдельный поток, иначе вы блокируете системную очередь рассылки сообщений. Пока она заблокирована интерфейс не будет перерисован. И сообщения к GUI контролам не будут доходить. Это кстати уже где-то в GUI разделе обсуждалось. |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |