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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поток Thread и SWT диалог, Создание диалога вместе с новым потоком 
V
    Опции темы
zeynor
Дата 8.11.2011, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте!

С потоками только начал обращаться из-за острой необходимости, и вот не получается разобраться с некоторыми моментами.

Суть в следующем: по нажатию кнопки из главного окна программы (вся графика на SWT) должно открываться диалоговое окно и запускаться новый поток, вызывающий определенные методы. В окне отображается информация о том, что происходит на данный момент в потоке.

Как пытаюсь сделать я:

Нажатие кнопки:
Код

...public widgetSelected(event e) 
{
MyThread mt = new MyThread(myData);
}


Класс MyThread:
Код

class MyThread implements Runnable
{
public static boolean go = true;
private Thread t;
private MyDataClass myData;
  
public MyThread(MyDataClass myData)
{
this.myData = myData;
t = new Thread(this);
t.setDaemon(true);
t.start();
}

public void run()
{
display.syncExec(new Runnable() {
    public void run(){
      MyDialog md = new MyDialog();
      md.open();
    }
  });

//Выполнение программы
while (go)
   myMethog(myData);
}
}


Класс MyDialog:
Код

class MyDialog extends Dialog
{
public MyDialog() {}
public Object open
{
this.shell.addShellListener(new MySListener());
//Добавление элементов
}

//Закрытие диалога
class MySListener implements ShellListener
{
public void shellClosed(ShellEvent arg0) 
{
MyThread.go = false;
}
}
}


Проблема в том, что не обновляется переменная "go", поток не завершает работу после закрытия диалога.

Пробовал делать по-другому: сначала запуск диалога, из него запуск потока, но та же проблема.
Единственное решение, которое у меня работало - как описано строчкой выше, но в классе MySListener принудительно закрываю поток (thread.stop()).
Насколько понял, этот вариант считается ненадежным и устаревшим.

Как можно выйти из этой ситуации?
Спасибо
PM MAIL   Вверх
Skynin
Дата 8.11.2011, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

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



Код

display.syncExec(new Runnable() {
    public void run(){
      MyDialog md = new MyDialog();
      md.open();
    }
  });

Нехорошо!
Зачем в Runnable запихивать создание элемента GUI? когда все равно syncExec запустит этот Runnable в потоке GUI?
"Толкем воду в ступе" или "масло масляным делаем"?

Цитата

из главного окна программы (вся графика на SWT) должно открываться диалоговое окно и запускаться новый поток

Вот пусть и:
1. Открывается окно
2. Запускаем поток в котором ничего нет из GUI элементов, кроме
2а. передаем ссылку нашего окна, и когда нужно ему что-то передать:
Код

display.syncExec(new Runnable() {
    public void run(){
      md.showIt( myDataFromOtherThread );
    }
  });

3. Когда окно закрывается, убиваем поток. Либо флагом (внутри должен обрабатываться) либо interrupt() ему
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
zeynor
Дата 8.11.2011, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за ответ!

Насколько понял, ссылку окна передаем в новый поток, и только по ссылке управляем поведением элементов в окне? Т.е. если допустим у нас данные в потоке получаются в цикле, то будет выглядеть примерно так:
Код

class MyThread implements Runnable
{
public void run()
{    
//Получаем нужные данные
....

for (int i=0; i<data.length(); i++)
{
display.syncExec(new Runnable() {
    public void run(){
      md.showIt( data[i] );
    }
  });
}
}


Или как-то по-другому?

И вопрос по поводу флага немного не понял, если у нас поступает информация о состоянии окна из самого окна (при закрытии к примеру), как передавать изменившийся флаг внутрь потока? 

interrupt попробую...

Буду благодарен за объяснения. Спасибо!
PM MAIL   Вверх
firedrago
Дата 8.11.2011, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



все зависит от конкретной задачи, и в идеале делать логику отдельно от GUI как сказал Skynin, но если для теста и на быструю руку то можно как в примере http://git.eclipse.org/c/platform/eclipse....s/Snippet7.java
пока элемент или диалог !isDisposed() делай, иначе выходи
PM MAIL   Вверх
zeynor
Дата 9.11.2011, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пока сделал таким образом:

1) Из главного окна запускаю диалоговое окно
2) Из диалогового окна запускаю поток (туда передаю ссылку на нужные данные и текущее диалоговое окно) и добавляю слушатель для обработки выхода из окна, куда вешаю interrupt:
Код

class MyDialog extends Dialog
{
private MyThread thread;
....

public Object open()
{
        thread = new MyThread(myData, this);
        thread.start();
}
...
class MyShellListener implements ShellListener
{
        public void shellClosed(ShellEvent arg0) {
            thread.interrupt();
        }
}
}


3) В самом потоке  делаю операции с нужными данными и изменяю информацию в диалоговом окне
4) Для каждой итерации получения данных в потоке проверяю условие isInterrupted, если false - продолжаю работу.

Что можете сказать по такому решению? 
Меня пока не устраивает, т.к. у меня данные получаются из сети, данные многоуровневые, много итераций. И для каждого вхождения в каждый метод (и внутри него) требуется ставить проверку условия isInterrupted.


Может есть какой-то более изящный способ?
PM MAIL   Вверх
firedrago
Дата 9.11.2011, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Вы используете чистый SWT или Eclipse RCP ? В RCP есть прекрасная штука под нозванием Job или UIJob. А если чистый SWT, то на мой взгляд, лучше проверять существование Dialoga чем Threada.... а то если по какой то причине вывалится получение данных, то пользователь будет сидеть и тупо смотреть на Dialog с текстом "Please wait...."

... хотя проверять надо и то и то....

Это сообщение отредактировал(а) firedrago - 9.11.2011, 11:03
PM MAIL   Вверх
zeynor
Дата 9.11.2011, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



firedrago,
Чистый SWT.

Пока сделал так, как написал, и все практически прекрасно работает. 
Проверка isDisposed не нужна, т.к. я передаю потоку interrupt по действию закрытия окна.

Единственный минус - пока что флаги поставил не во все существенные места, и в определенных случаях вываливается ошибка Widget not disposed.
Но это уже не проблема, т.к. такую же ошибку для других ситуаций решил.

Спасибо всем, кто помог!
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.0471 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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