【问题标题】:Run code every second by using System.currentTimeMillis()使用 System.currentTimeMillis() 每秒运行一次代码
【发布时间】:2012-10-29 12:43:48
【问题描述】:

我正在尝试使用 System.currentTimeMillis(); 每秒运行一行代码。

代码:

     while(true){
           long var = System.currentTimeMillis() / 1000;
           double var2 = var %2;

           if(var2 == 1.0){

               //code to run

           }//If():

        }//While

我要运行的代码多次运行,因为 var2 由于无限的整个循环而多次设置为 1.0。我只想在 var2 第一次设置为 1.0 时运行代码行,然后每次 var2 在 0.0 后变为 1.0 时再次运行。

【问题讨论】:

  • 我真的应该开始像你一样将 cmets 放在循环和决策上。做得很好。
  • @Andy - 请不要像这样将 cmets 放在右括号上。使用您的 IDE 的“显示匹配的括号”和/或重构代码,这样您就没有太长以至于您需要执行此操作的块。
  • @StephenC,我认为安迪是在讽刺。他的评论对 OP 没有太大帮助。

标签: java loops time


【解决方案1】:

如果你想忙着等待秒数改变你可以使用下面的。

long lastSec = 0;
while(true){
    long sec = System.currentTimeMillis() / 1000;
    if (sec != lastSec) {
       //code to run
       lastSec = sec;
    }//If():
}//While

更有效的方法是休眠到下一秒。

while(true) {
    long millis = System.currentTimeMillis();
    //code to run
    Thread.sleep(1000 - millis % 1000);
}//While

另一种方法是使用 ScheduledExecutorService

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();

ses.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        // code to run
    }
}, 0, 1, TimeUnit.SECONDS);

// when finished
ses.shutdown();

这种方法的优点是

  • 您可以让多个不同时期的任务共享同一个线程。
  • 您可以执行非重复延迟或异步任务。
  • 您可以在另一个线程中收集结果。
  • 您可以使用一个命令关闭线程池。

【讨论】:

  • 谢谢我用了你给的第一个选项
【解决方案2】:

我会使用 java executor 库。您可以创建一个ScheduledPool,它需要一个可运行的并且可以在您想要的任何时间段内运行。例如

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new MyRunnable(), 0, 5, TimeUnit.SECONDS);

将每 5 秒运行一次 MyRunnable 类。 MyRunnable 必须实现 Runnable。这样做的问题在于,它每次都会(有效地)创建一个新线程,这可能是可取的,也可能不是可取的。

【讨论】:

    【解决方案3】:

    您应该必须使用 java.util.Timerjava.util.TimerTask 类。

    【讨论】:

    • 如果代码不在 UI 线程中(原因很明显),他也可以使用 Thread.sleep
    • 遗留的定时器和定时器任务 API 很糟糕。没有合理的异常处理,一旦发生异常,整个计时器线程就会被杀死。你必须重新运行它。它对系统时钟的变化也很敏感,您必须取消触摸系统时钟(并关闭 DST!)。现代 java util 并发执行器服务 API 没有这些特殊问题。
    【解决方案4】:

    使用Thread.sleep(); 将非常适合您的情况。

     while(true)
     {
        Thread.sleep(1000); // Waiting before run.
        // Actual work goes here.
     }
    

    【讨论】:

    • 这不是每秒运行一次。这会在完成后等待一秒钟。运行本身不一定需要 0 秒。假设运行需要 200 毫秒,那么它实际上应该等待 800 毫秒。请改用 java util 并发执行器服务。
    • 谢谢,但我不想每秒都停止 Java 主类。使用 System.currentTimemillis 有什么办法吗?
    • @BalusC 你是对的。但这个答案只是为了给 OP 一个小费。他应该配置睡眠时间。
    【解决方案5】:

    首选方式:

    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    

    然后传入 Runnables 像:

    scheduler.scheduleWithFixedDelay(myRunnable, initDelay, delay, TimeUnit.MILLISECONDS);
    

    我不会使用计时器。调度程序旨在处理计时器可能导致的问题。此外,Thread.sleep 适用于一个简单的程序,您可以快速编写该程序以用于概念证明类型的东西,但我不会在企业世界中使用它。

    【讨论】:

      猜你喜欢
      • 2018-12-19
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 2015-03-27
      • 1970-01-01
      相关资源
      最近更新 更多