Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Заставить бы Thread возвращать значение, метод вызыв. Thread и возвр. ее результа 
:(
    Опции темы
_Y_
  Дата 25.1.2007, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Предистория:  В главном потоке вызывается метод. Этот метод делает вычисления и возвращает значение. Выяснилось, что дело медленное и надо показывать прогресс монитор, а для этого вычисления выносить в отдельный Thread.

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

private class ThreadCalculate extends Thread {
    public int valueResult;
.......
    public void run(){
        .........
        valueResult = something;
    }
}

Но встала проблема: как дождаться окончания работы Thread, чтобы эту переменную прочитать?
Попробовал сделать так (нарыл что-то подобное в сети и модифицировал):            
Код

ThreadCalculate threadCalculate = new ThreadCalculate();
threadCalculatePvalues.start();
try {
    do {
        threadCalculatePvalues.join(100);
        threadCalculatePvalues.sleep(100);
    } while(threadCalculatePvalues.isAlive());
} catch (InterruptedException e) {}
return threadCalculate.valueResult;

Подвисает GUI, а если убираю блок try-catch со всем содержимым, то, естественно, значение threadCalculate.valueResult читается до того, как закончился рассчет smile 

Эпилог: Понимаю, что изначально надо было делать структуру программы с рассчетом на многопоточность, не бейте. Сейчас переделывать уже будет слишком много. Можно ли как то решить?
 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
s8e8r8g8e
Дата 25.1.2007, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 12.5.2006

Репутация: 1
Всего: 1



ну да подвисает...
вычислитнельный поток замораживается на 100 мсек.. почти сразу за этим основной поток ждёт 100 мсек а не закончится ли вычислительный.. после чего отправляет его опять спать, этак он никогда и не работает кроме как первые 100 мсек smile, а значит и основой никогда из цикла не выйдет..
а где здесь прогрессбар апдейтится?
PM MAIL   Вверх
_Y_
Дата 25.1.2007, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Цитата(s8e8r8g8e @ 25.1.2007,  22:04)
ну да подвисает...
... этак он никогда и не работает кроме как первые 100 мсек smile, а значит и основой никогда из цикла не выйдет..
а где здесь прогрессбар апдейтится?

Я и сам вижу что фигня это. Но как сделать не знаю.  А прогрессбар апгрейдится внутри метода run(), но это не важно, прогрессбар может быть и indeterminate. Он все равно подвисает вместе с GUI smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
shimopus
Дата 26.1.2007, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 25.8.2006

Репутация: 1
Всего: 1



Предлагаю проверять живость потока, который в свою очередь после того как посчитает значение переменной запишет либо в общедоступный класс, либо дернет метод главного потока.

Код

 do 
{
        
} 
while(threadCalculatePvalues.isAlive());
//Здесь читаем готовое значение 
//посчитанное в потоке и сохраненное 
//где-нибудь в общедоступном месте

PM ICQ Skype GTalk   Вверх
Stampede
Дата 26.1.2007, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



_Y_, ты пытаешься снаружи опрашивать состояние вычислительного потока, и от этого все твои трудности. На самом деле проблема решается выворачиванием ролей наизнанку: визуальный компонент регистрируется слушателем событий твоего потока, а поток уже по достижении определенных состояний/контрольных точек вызывает методы слушателя. Вот как это может выглядеть на Java.

Описываем интерфейс слушателя:

Код

public interface ProgressListener {
  public void jobStarted();
  public void completed(int percentage);
  public void jobDone();
}


В классе-потоке делаем так:

Код

public class Calculation implements Runnable {
  private ProgressListener listener;

  public void setProgressListener(ProgressListener listener) {
    this.listener = listener;
  }

  public void run() {
    listener.jobStarted();

    for (int = 0; i < 100; i++) {
      // do some calculation
      listener.completed(i + 1);
    }

    listener.jobDone();
  }
}


Надеюсь, понятно, что пример упрощенный, но в целом идея примерно такая. На практике слушателей в общем случае может быть больше одного, поэтому слушателей обычно хранят в списке, а чтобы упростить вызов оповещений, дополнительно объявляют методы типа fireJobStarted(), fireJobDone() и т. д., и в них уже перебирают и в цикле дергают соответствующий метод каждого слушателя.

Где-то примерно вот так.
PM WWW   Вверх
_Y_
Дата 26.1.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Цитата(shimopus @ 26.1.2007,  00:08)
Предлагаю проверять живость потока...
Код

 do 
{
} 
while(threadCalculatePvalues.isAlive());


И это пробовал, и с приоритетом потоков играл. Все равно перерисовка GUI подвисает smile 

Цитата(Stampede @ 26.1.2007, 00:32)
_Y_, ты пытаешься снаружи опрашивать состояние вычислительного потока, и от этого все твои трудности. На самом деле проблема решается выворачиванием ролей наизнанку...

Это я понимаю. Можно через листенеры делать, а можно, наверное, просто передать потоку ссылку на объект и в конце вычислений просто вызвать метод объекта передав параметр содержащий результат. Проблема-то в том, что этот "правильный" подход потребует серьезной переделки структуры уже работающей программы. Вот и хочется обойтись "малой кровью", т.е. заставить метод запустить поток и обождать результата, но, при этом, не блокировать GUI.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
shimopus
Дата 26.1.2007, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 25.8.2006

Репутация: 1
Всего: 1



а как ты хочешь, чтобы  GUI получило результат выполнения операции не ожидая его? Не переделывая ничего не думаю, что что-нибудь получится...
PM ICQ Skype GTalk   Вверх
_Y_
Дата 26.1.2007, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 5
Всего: 34



Цитата(shimopus @ 26.1.2007,  12:59)
а как ты хочешь, чтобы  GUI получило результат выполнения операции не ожидая его?

Да нет. Я просто хотел чтобы GUI перерисовывался не дожидаясь окончания работы метода вызвавшего Thread. Ему результат не нужен. Но, вы все, видимо, правы и Java в этом деле обману не поддается smile 

Это сообщение отредактировал(а) _Y_ - 26.1.2007, 19:07


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
powerOn
Дата 26.1.2007, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата(_Y_ @  26.1.2007,  19:07 Найти цитируемый пост)
Я просто хотел чтобы GUI перерисовывался не дожидаясь окончания работы метода вызвавшего Thread.


Нужно вынести логику в отдельный поток, иначе вы блокируете системную очередь рассылки сообщений. Пока она заблокирована интерфейс не будет перерисован. И сообщения к GUI  контролам не будут доходить. Это кстати уже где-то в GUI разделе обсуждалось.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0560 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.