Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Timer `n` Thread


Автор: zone51 12.2.2007, 23:48
Товарищи, доброго времени суток всем! Помогите пожалуйста разобраться с проблемой. Есть GUI форма и на ней 2 кнопки- одна запускает поток, в потоке крутится таймер. Другой кнопкой поток стоппится. Использую java.util.timer. То есть в одном методе ActionListener что то вроде
Код

Thread t=new Thread()
...
t.start();

В другом
Код

t.terminate();

Проблема в том что запускается то хорошо, но никак нельзя остановить. К тому же поток крутится но из других методов класса в том числе из второго листенера этот поток не виден. то есть он всегда TERMINATED. Помогите разобрацца. Почитал доку вроде таймер свой поток запускает. Пытался сделать чисто таймером. То же самое. Таймер не стопится. В чем дело? Спасибо. smile  smile 

Автор: Hidrag 13.2.2007, 00:13
Если тебе нужно выполнять что то в другом потоке и при этом управлять им то можно сделать так:

Создай класс, наследуй его от потока, определи в нем метод run:
Код

public class StartThread extends Thread {
    
   public boolean stop=false;
   public boolean isReady=false;

    public StartThread() {
    }
    
    public void run() {
       while (!stop) {
           // выполняй то что нужно
           isReady=true; //когда обработка закончится (если она заанчивается) присвой "истину"
        }
    }



То есть гоняешь цикл пока переменная не истина...

В классе из которого будешь запускать, можно сделать что то типа жтого:
Код

    public void start() {
        StartThread r = new StartThread();
        r.start();
        boolean stop = false;
        do {
            try {
                Thread.sleep(1000); //чтобы не загружать процессор
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            boolean w = r.isReady;  // так ты узнаешь что поток отработал
            if (w) stop=true;
        } while (!stop);
    }


или так:
Код

    public void start() {
        StartThread r = new StartThread();
        r.start();
        ***
        r.stop=true; //останавливаешь поток
    }


Автор: zone51 13.2.2007, 01:17
Hidrag
Я как делаю:
Код

class cl extends Thread{

public void run(){
//Тут запускается таймер и крутится
}

}

А в GUI 
Код

class gui{

public static cl newcl;

button1.addActionListener(
public void actionPerformed(ActionEvent e){

newcl=new cl();
newcl.start();

});

button2.addActionListener(
public void actionPerformed(ActionEvent e){

if(newcl.isAlive()){
newcl.interrupt();
}

});
}


так вот во второй процедуре для button2 никак не видится cl. Он всегда (поток) остановлен.
То что вы предлагаете я конечно попробую, но неужели нельзя сделать все стандартно?
Кстати
Цитата

или так:

Код

public void start() {
        StartThread r = new StartThread();
        r.start();
        ***
        r.stop=true; //останавливаешь поток
}
  

В моем случае проблема не в этом, я думаю что r.stop=true не будет видна точно как и newcl.interrupt()
Спасибо.

Автор: Hidrag 13.2.2007, 09:51
В классе потока обьяви пабликом таймер, опиши те действия которые таймер крутит в конструкторе класса, а в run стартуй таймер. Таким образом поток всегда будет работать.

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

И наверное не стоит создавать экземпляр потока по нажатию кнопки вынеси создание в конструктор а по нажатию первой кнопки запуская старт у таймера а по нажатию второй кнопки стоп таймера.

А зачем public static cl newcl; статиком сделал?

Автор: zone51 13.2.2007, 11:27
Hidrag
Цитата

А зачем public static cl newcl; статиком сделал?

На всякий
Выносить отдельной кнопкой создание в конструкторе нельзя-требования к интерфейсу.
К тому же  в java.util.Timer есть только cancel() и он не работает из другой процедуры. Не пойму в чем дело.

Автор: Hidrag 13.2.2007, 11:51
Цитата(zone51 @  13.2.2007,  11:27 Найти цитируемый пост)
Выносить отдельной кнопкой создание в конструкторе нельзя

Что что? smile

Еще раз: зачем создавать экземпляр класса потока по нажатию кнопки? Если ты каждый раз будешь нажимать эту кнопку у тебя будут плодиться инстансы и как ты будешь отслеживать какой из них тормозить?

По нажатию стартуй  или останавливай таймер в экземпляре класса потока. У таймера есть воиды старт и стоп, по крайней мере в 1.5.

...и убери статик

..счас пример накидаю...

Автор: LSD 13.2.2007, 12:08
Почитай FAQ по многопоточному программированию.

Автор: Hidrag 13.2.2007, 12:18
Цитата(zone51 @  13.2.2007,  11:27 Найти цитируемый пост)
java.util.Timer есть только cancel() 

Да ты был прав насчет него! Но ведь есть более удобный таймер в свинге! Вот пример:

Класс с кнопками:
Код

package primer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class MainClass extends JFrame {
    
    public MainClass() {
        final Potok p = new Potok();
        JPanel pan = new JPanel();
        JButton b1 = new JButton("Start");
        JButton b2 = new JButton("Stop");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                p.start();
            }
        });
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                p.t.stop();
            }
        });
        pan.add(b1);
        pan.add(b2);
        setContentPane(pan);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(300, 200);
        setVisible(true);
    }
    public static void main(String[] args) {
        new MainClass();
    }
    
}


Класс потока:
Код

package primer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class Potok extends Thread{
    
    public Timer t = new Timer(100, new ActionListener() {
        int i;
        public void actionPerformed(ActionEvent e) {
            i++;
            System.out.println("preved!"+i);            
        }
    });
    
    public Potok() {
    }
    
    public void run() {
        t.start();
    }
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)