Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中重复调用线程?_Java_Multithreading - Fatal编程技术网

如何在Java中重复调用线程?

如何在Java中重复调用线程?,java,multithreading,Java,Multithreading,我希望每500毫秒在后台执行一个线程。为此,我扩展了一个线程,实现了ActionListener,并将扩展的类放入计时器中。计时器每500毫秒调用一次run()。然而,当这个线程从互联网下载东西时,我的整个Swing GUI都冻结了。我希望它在后台运行,而不会在等待IO完成时冻结GUI。我还要求下载程序在等待500毫秒之前完成下载 调用gogogo()初始化整个过程: public final class Downloader extends Thread implements ActionLi

我希望每500毫秒在后台执行一个线程。为此,我扩展了一个线程,实现了ActionListener,并将扩展的类放入计时器中。计时器每500毫秒调用一次run()。然而,当这个线程从互联网下载东西时,我的整个Swing GUI都冻结了。我希望它在后台运行,而不会在等待IO完成时冻结GUI。我还要求下载程序在等待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();
}
}

嗯,最有可能需要做的就是降低线程优先级,这样它就不会占用您所有的资源。

尝试使用java util计时器或ScheduledExecutorService,而不是使用swing计时器。摆动计时器共享一个预先存在的计时器线程,这可能导致冻结

java教程中的建议:

通常,我们建议对GUI相关任务使用Swing计时器而不是通用计时器,因为Swing计时器都共享相同的、预先存在的计时器线程,并且GUI相关任务会在事件调度线程上自动执行。但是,如果您不打算从计时器触摸GUI,或者需要执行长时间的处理,则可以使用通用计时器


您需要在每个计时器操作上启动线程。调用线程的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);
    }
}

只需启动一次线程,使其循环,并在每次迭代中执行
thread.sleep(500L)
。每500毫秒开始一个全新的线程可能更有意义。如果可以避免,则没有理由产生相关成本。

如果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()停止重复任务的执行。

它不会滞后。它会阻止GUI运行。如果我一次只想让一个下载程序下载东西呢?那么我会让下载程序在迭代之间休眠。您的GUI冻结的原因是线程从未启动…我觉得自己真的很笨。:)嗯,我记得我用了一个while循环使线程在另一个程序中继续运行。我不知道我为什么忘了