Как вы неоднократно вызываете поток в Java? - PullRequest
3 голосов
/ 16 марта 2009

Я хочу, чтобы поток выполнялся в фоновом режиме каждые 500 миллисекунд. Для этого я расширил Thread, реализовал ActionListener и поместил класс, который я расширил, в Timer. Таймер вызывает run () каждые 500 миллисекунд. Тем не менее, весь мой графический интерфейс Swing зависает, когда этот поток загружает материалы из Интернета. Я хочу, чтобы он работал в фоновом режиме, не замораживая графический интерфейс, пока он ожидает завершения ввода-вывода. Я также загрузчик, чтобы закончить загрузку, прежде чем мы будем ждать 500 миллисекунд.

gogogo () вызывается для инициализации всего процесса:

public final class Downloader extends Thread implements ActionListener
{
public static void gogogo()
{
    t= new Downloader();
    new Timer(500, (ActionListener) t).start();

}

public void run() 
{
    doStuff(); //the code that i want repeatedly called
}

public void actionPerformed(ActionEvent e) 
{
    run();
}
}

Ответы [ 5 ]

8 голосов
/ 16 марта 2009

Просто запустите поток один раз, сделайте его зацикленным и выполняйте Thread.sleep(500L) с каждой итерацией. Это, вероятно, имеет больше смысла, чем запускать новую нить каждые 500 мс. Нет причин нести связанные с этим расходы, если вы можете их избежать.

1 голос
/ 16 марта 2009

Если ваш GUI зависает, то ваша длинная задача (doStuff), вероятно, выполняется в потоке диспетчеризации событий. В то время как он захватывает этот поток, другие действия не могут его использовать.

Если вы пытаетесь запустить задачу несколько раз, вам лучше воспользоваться классом TimerTask

public class Downloader extends TimerTask {
    public void run() {
        doStuff();
    }
}

... elsewhere ...

Timer myTimer = new Timer();

public void gogogo() {
    myTimer.scheduleAtFixedRate(new Downloader(), 0, 500);
}

Это немного отличается тем, что ваша задача будет выполняться каждые 500 мс, а не с задержкой в ​​500 мс. Когда вы закончите, просто используйте myTimer.cancel (), чтобы остановить повторяющееся выполнение задачи.

1 голос
/ 16 марта 2009

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

Рекомендация из руководства по Java:

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

0 голосов
/ 16 марта 2009

Вам нужно запускать поток при каждом действии таймера. Вызов метода run () потока не запускает поток.

public void actionPerformed(ActionEvent e) 
{
        //run();
Downloader t = new Downloader();
t.start();

}

Может быть лучше использовать анонимный класс для actionlistener. Извините за синтаксис Java, но я не проверил его ...

  new Timer(500, 
      new ActionListener(){
            public void actionPerformed(ActionEvent e) 
            {
               //run();
               Downloader t = new Downloader();
               t.start();

            }
          }).start();

Или без таймера ...

public static void gogogo()
{
        t= new Downloader();
        t.start();

}

public void run() 
{
    while(true){
        doStuff(); //the code that i want repeatedly called

        Thread.sleep(500);
    }
}
0 голосов
/ 16 марта 2009

Хм, скорее всего, все, что вам нужно сделать, это уменьшить приоритет потока, чтобы он не съел все ваши ресурсы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...