Java计时器不会在启动新的计时器任务之前等待上一个计时器任务完成

Java计时器不会在启动新的计时器任务之前等待上一个计时器任务完成,java,timer,modal-dialog,Java,Timer,Modal Dialog,我正在用Java编写一个应用程序,我陷入了以下困境:经过一段时间后,将显示inputDialogJOptionPane。因为间隔很短,即10秒,如果我延迟与第一个对话框的交互,那么第二个对话框将在我之后立即出现。有没有办法避免这种情况?我以为那个程序会等待我的输入 代码: Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public v

我正在用Java编写一个应用程序,我陷入了以下困境:经过一段时间后,将显示inputDialogJOptionPane。因为间隔很短,即10秒,如果我延迟与第一个对话框的交互,那么第二个对话框将在我之后立即出现。有没有办法避免这种情况?我以为那个程序会等待我的输入

代码:

Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
          @Override
          public void run() {
            String task = JOptionPane.showInputDialog(null, "What are you doing now???", "");
          }
        }, 10*1000, 10*1000);
尝试从计时器任务内部停止/启动计时器

尝试从计时器任务内部停止/启动计时器


如果任务已经在运行,只需签入run方法,并在运行时返回

添加一个变量

static boolean isRunning = false;
到您的TimerTask实现类。然后,您的运行方法如下所示:

 public void run() {
     if (isRunning == false) {
         isRunning = true;

         // your code

         isRunning = false;
     }
 }

如果任务已经在运行,只需签入run方法,并在运行时返回

添加一个变量

static boolean isRunning = false;
到您的TimerTask实现类。然后,您的运行方法如下所示:

 public void run() {
     if (isRunning == false) {
         isRunning = true;

         // your code

         isRunning = false;
     }
 }
[编辑] 下面的代码没有使用scheduleAtFixedRate,因此其结论可能是错误的。。。 永远不要相信互联网上的那些家伙:

[原件] 我喜欢和我一样懒惰的人:

计时器等待。它一次只运行一个任务

**使用java-1.8.0-openjdk进行测试

代码scala,但它使用的是Java计时器:

import java.util.{Timer, TimerTask}

object O {
    val iGen = new AtomicInteger()

    def main(args: Array[String]): Unit = {
        val timer = new Timer()

        val timerTask = new TimerTask {
            override def run(): Unit = {
                val tid = iGen.incrementAndGet()
                println(s"--- task #$tid started")
                Thread sleep(5000)
                println(s"--- task #$tid done")
            }
        }

        timer.schedule(timerTask, 0, 1000)
    }
}
输出:

--- task #1 started
--- task #1 done
--- task #2 started
--- task #2 done
--- task #3 started
--- task #3 done
--- task #4 started
--- task #4 done
--- task #5 started
--- task #5 done
--- task #6 started
--- task #6 done
--- task #7 started
--- task #7 done
--- task #8 started
--- task #8 done
--- task #9 started
--- task #9 done
--- task #10 started
--- task #10 done
--- task #11 started
--- task #11 done
--- task #12 started
--- task #12 done
--- task #13 started
--- task #13 done
--- task #14 started
--- task #14 done
--- task #15 started
--- task #15 done
--- task #16 started
--- task #16 done
--- task #17 started
--- task #17 done
--- task #18 started
--- task #18 done
--- task #19 started
--- task #19 done
--- task #20 started
--- task #20 done
--- task #21 started
--- task #21 done
--- task #22 started
--- task #22 done
--- task #23 started
--- task #23 done
--- task #24 started
--- task #24 done
--- task #25 started
--- task #25 done
--- task #26 started
--- task #26 done
--- task #27 started
--- task #27 done
--- task #28 started
--- task #28 done
--- task #29 started
--- task #29 done
--- task #30 started
--- task #30 done
--- task #31 started
--- task #31 done
--- task #32 started
--- task #32 done
--- task #33 started
--- task #33 done
--- task #34 started
--- task #34 done
--- task #35 started
--- task #35 done
--- task #36 started
--- task #36 done
--- task #37 started
--- task #37 done
--- task #38 started
[编辑] 下面的代码没有使用scheduleAtFixedRate,因此其结论可能是错误的。。。 永远不要相信互联网上的那些家伙:

[原件] 我喜欢和我一样懒惰的人:

计时器等待。它一次只运行一个任务

**使用java-1.8.0-openjdk进行测试

代码scala,但它使用的是Java计时器:

import java.util.{Timer, TimerTask}

object O {
    val iGen = new AtomicInteger()

    def main(args: Array[String]): Unit = {
        val timer = new Timer()

        val timerTask = new TimerTask {
            override def run(): Unit = {
                val tid = iGen.incrementAndGet()
                println(s"--- task #$tid started")
                Thread sleep(5000)
                println(s"--- task #$tid done")
            }
        }

        timer.schedule(timerTask, 0, 1000)
    }
}
输出:

--- task #1 started
--- task #1 done
--- task #2 started
--- task #2 done
--- task #3 started
--- task #3 done
--- task #4 started
--- task #4 done
--- task #5 started
--- task #5 done
--- task #6 started
--- task #6 done
--- task #7 started
--- task #7 done
--- task #8 started
--- task #8 done
--- task #9 started
--- task #9 done
--- task #10 started
--- task #10 done
--- task #11 started
--- task #11 done
--- task #12 started
--- task #12 done
--- task #13 started
--- task #13 done
--- task #14 started
--- task #14 done
--- task #15 started
--- task #15 done
--- task #16 started
--- task #16 done
--- task #17 started
--- task #17 done
--- task #18 started
--- task #18 done
--- task #19 started
--- task #19 done
--- task #20 started
--- task #20 done
--- task #21 started
--- task #21 done
--- task #22 started
--- task #22 done
--- task #23 started
--- task #23 done
--- task #24 started
--- task #24 done
--- task #25 started
--- task #25 done
--- task #26 started
--- task #26 done
--- task #27 started
--- task #27 done
--- task #28 started
--- task #28 done
--- task #29 started
--- task #29 done
--- task #30 started
--- task #30 done
--- task #31 started
--- task #31 done
--- task #32 started
--- task #32 done
--- task #33 started
--- task #33 done
--- task #34 started
--- task #34 done
--- task #35 started
--- task #35 done
--- task #36 started
--- task #36 done
--- task #37 started
--- task #37 done
--- task #38 started

我必须在单独的块中或在运行方法中执行此操作吗?我必须在单独的块中或在运行方法中执行此操作吗?如果这是一个Swing应用程序,则不应使用java.util.Timer,因为它可能会从Swing事件线程调用Swing代码。考虑使用Swing定时器,并在打开下一个对话框之前测试前一个对话框是否已关闭。我应该继续吗?就我个人而言,从一开始就改变程序的设计。我会创建一个完整的swing GUI,不会向用户抛出对话框。我同意,但我只需要一个输入对话框……它是供个人使用的。如果这是一个swing应用程序,你不应该使用java.util.Timer,因为它有从swing事件线程调用swing代码的风险。考虑使用Swing定时器,并在打开下一个对话框之前测试前一个对话框是否已关闭。我应该继续吗?就我个人而言,从一开始就改变程序的设计。我会创建一个完整的swing GUI,不会向用户抛出对话框。我同意,但我只需要一个输入对话框……它是供个人使用的,尽管我采用了另一种实现,我喜欢这一个。@py_脚本请说明您采用和实施了哪一个备选方案,以便对其他人有所帮助。我发现有一个很小的可能性,即在这里出现了一些漏洞,因为无法保证在检查后立即执行isRunning=true。我们可能会遇到另一个线程执行速度更快的竞争条件。确保这一点的唯一方法是通过同步线程IMHO,但是如果计时器事件花费更长的时间,我们可能会看到反压力随着计时器事件的增加而增加。尽管我采用了另一种实现,我喜欢这一个。@py_脚本请说明您采用和实施了哪一个备选方案,以便对其他人有所帮助。我发现有一个很小的可能性,即在这里出现了一些漏洞,因为无法保证在检查后立即执行isRunning=true。我们可能会遇到另一个线程执行速度更快的竞争条件。确保这一点的唯一方法是通过同步线程IMHO,但是如果计时器事件花费更长的时间,我们可能会看到反压力。