【问题标题】:Print "hello world" every X seconds每 X 秒打印一次“hello world”
【发布时间】:2012-10-06 04:21:49
【问题描述】:

最近我一直在使用带有大量数字的循环来打印出Hello World

int counter = 0;

while(true) {
    //loop for ~5 seconds
    for(int i = 0; i < 2147483647 ; i++) {
        //another loop because it's 2012 and PCs have gotten considerably faster :)
        for(int j = 0; j < 2147483647 ; j++){ ... }
    }
    System.out.println(counter + ". Hello World!");
    counter++;
}

我知道这是一种非常愚蠢的做法,但我从未在 Java 中使用过任何计时器库。如何修改上述内容以每隔 3 秒打印一次?

【问题讨论】:

  • 虽然以下答案显然应该回答您的问题,但您还应该注意,您这样做的方式会导致每台机器上的时间间隔不同。取决于它运行编译器的速度。

标签: java timer


【解决方案1】:

如果您想执行周期性任务,请使用ScheduledExecutorService。具体ScheduledExecutorService.scheduleAtFixedRate

代码:

Runnable helloRunnable = new Runnable() {
    public void run() {
        System.out.println("Hello world");
    }
};

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(helloRunnable, 0, 3, TimeUnit.SECONDS);

【讨论】:

  • 我希望其他人也对此表示赞同。 Thread.sleep() 可能最适合 OP 中的代码,但它是一个相当业余的轮子改造。专业的软件工程师将使用久经考验且值得信赖的 API,例如 TimerTask。不过,ScheduledExecutorService 更好;请参阅 Brian Goetz 等人的 Java 并发实践。后一类已经存在了近十年——很遗憾,所有其他答案都忽略了它。
  • @MichaelScheper,谢谢,我很高兴看到这个答案终于超过了TimerTask 变体。有趣的是,我注意到接受的答案实际上是不正确的:\ 除了两个 API 的年龄,ScheduledExecutorService 只是更直观地声明。使用TimeUnit 作为参数可以更清楚地知道发生了什么。像5*60*1000 // 5 minutes 这样的代码时代已经一去不复返了。
  • @TimBender 我注意到您的 period 参数为 3。我无法找到是以秒还是毫秒为单位的。我想让它每 500 毫秒(半秒)运行一次。
  • 啊,我明白了。第四个参数可让您指定时间,例如TimeUnit.MILLISECONDS。
  • @TerryCarter 在 Java8+ 中你可以改为使用Runnable helloRunnable = () -&gt; { /*code */ };,这样更漂亮;)
【解决方案2】:

您还可以查看TimerTimerTask 类,您可以使用它们来安排您的任务每n 秒运行一次。

您需要一个扩展TimerTask 并覆盖public void run() 方法的类,该方法将在您每次将该类的实例传递给timer.schedule() 方法时执行..

这是一个示例,它每 5 秒打印一次 Hello World:-

class SayHello extends TimerTask {
    public void run() {
       System.out.println("Hello World!"); 
    }
}

// And From your main() method or any other method
Timer timer = new Timer();
timer.schedule(new SayHello(), 0, 5000);

【讨论】:

  • 请注意,2-param schedule 方法将在指定的延迟后执行一次。需要使用 3 参数 schedulescheduleAtFixedRate
  • @TimBender 只是想知道 OP 是否真的完成了他的任务;)无论如何,现在我更愿意使用 ExecutorService 来完成这些任务。这确实是对传统 Thread API 的一大改进。只是在回答的时候没用过。
  • Timer timer = new Timer(true); 应设置为 true 作为一个守护进程。除非您希望计时器在关闭应用程序后仍然运行。
  • 请记住,此解决方案使用“完成上一个任务后的固定延迟”,这意味着延迟在上一个周期完成后开始。如果进程被延迟(例如垃圾收集),那么计时将被关闭。如果您想要准确性,例如对于长时间运行的线程,您应该与日期同步
  • 在 Eclipse 中加注星标后如何停止此计时器?即使我关闭它运行正确吗?
【解决方案3】:

尝试这样做:

Timer t = new Timer();
t.schedule(new TimerTask() {
    @Override
    public void run() {
       System.out.println("Hello World");
    }
}, 0, 5000);

此代码将每 5000 毫秒(5 秒)运行打印到控制台 Hello World。 欲了解更多信息,请阅读https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html

【讨论】:

    【解决方案4】:

    我用计时器解决了这个问题,希望对您有所帮助。我使用了来自同一包的java.util.TimerTimerTask 的计时器。见下文:

    TimerTask task = new TimerTask() {
    
        @Override
        public void run() {
            System.out.println("Hello World");
        }
    };
    
    Timer timer = new Timer();
    timer.schedule(task, new Date(), 3000);
    

    【讨论】:

      【解决方案5】:

      您可以在 for 循环中使用 Thread.sleep(3000)

      注意:这需要try/catch 块。

      【讨论】:

      • 我不喜欢这个解决方案,我认为这是一个变通方案,而不是真正的解决方案
      • 我否决了这个解决方案。你永远不应该只为了等待下一件事情而让一个线程休眠。无论是哪种编程语言,您的程序都应该满足任何需求,并“保持可用”以应对可能出现的下一件事情。
      【解决方案6】:
      public class HelloWorld extends TimerTask{
      
          public void run() {
      
              System.out.println("Hello World");
          }
      }
      
      
      public class PrintHelloWorld {
          public static void main(String[] args) {
              Timer timer = new Timer();
              timer.schedule(new HelloWorld(), 0, 5000);
      
              while (true) {
                  try {
                      Thread.sleep(2000);
                  } catch (InterruptedException e) {
                      System.out.println("InterruptedException Exception" + e.getMessage());
                  }
              }
          }
      }
      

      创建无限循环广告调度任务已配置。

      【讨论】:

        【解决方案7】:

        最简单的方法是将主线程设置为休眠 3000 毫秒(3 秒):

        for(int i = 0; i< 10; i++) {
            try {
                //sending the actual Thread of execution to sleep X milliseconds
                Thread.sleep(3000);
            } catch(InterruptedException ie) {}
            System.out.println("Hello world!"):
        }
        

        这将使线程停止至少 X 毫秒。线程可能会休眠更多时间,但这取决于 JVM。唯一可以保证的是线程将至少休眠那些毫秒。看看Thread#sleep 文档:

        使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性

        【讨论】:

        • 谢谢@Luiggi。无论我在哪台机器 (CPU) 上运行 Java,它都将始终确保它是 3000 毫秒,对吗?
        • @NandkumarTekale 需要详细说明吗?
        • @meiryo 它将停止线程至少 X 毫秒。线程可能会休眠更多时间,但这取决于 JVM。唯一可以保证的是线程至少会休眠这些毫秒。
        • 警告:如果这不是实时系统,睡眠时间至少为 3000 毫秒,但可能更长。如果您想要 3000 毫秒的睡眠,尤其是在有生命危险的地方(医疗仪器、控制飞机等),您应该使用实时操作系统。
        • @LuiggiMendoza 是否有不停止执行的解决方案? hello world 只是一个例子。我实际上想每 3 秒从 UDP 客户端发送一个简单的 DatagramPacket 到它的服务器。 Thread.sleep 合适吗?
        【解决方案8】:

        使用java.util.TimerTimer#schedule(TimerTask,delay,period) 方法会帮助你。

        public class RemindTask extends TimerTask {
            public void run() {
              System.out.println(" Hello World!");
            }
            public static void main(String[] args){
               Timer timer = new Timer();
               timer.schedule(new RemindTask(), 3000,3000);
            }
          }
        

        【讨论】:

          【解决方案9】:

          这是在java中使用线程的简单方法:

          for(int i = 0; i< 10; i++) {
              try {
                  //sending the actual Thread of execution to sleep X milliseconds
                  Thread.sleep(3000);
              } catch(Exception e) {
                  System.out.println("Exception : "+e.getMessage());
              }
              System.out.println("Hello world!");
          }
          

          【讨论】:

            【解决方案10】:

            他说的。您可以随心所欲地处理异常,但是 Thread.sleep(毫秒); 是最好的路线。

            public static void main(String[] args) throws InterruptedException {
            

            【讨论】:

              【解决方案11】:

              这是在线程构造器中使用 Runnable 接口的另一种简单方法

              public class Demo {
                  public static void main(String[] args) {
                      Thread t1 = new Thread(new Runnable() {
              
                          @Override
                          public void run() {
                              for(int i = 0; i < 5; i++){
                                  try {
                                      Thread.sleep(3000);
                                  } catch (InterruptedException e) {
                                      // TODO Auto-generated catch block
                                      e.printStackTrace();
                                  }
                                  System.out.println("Thread T1 : "+i);
                              }
                          }
                      });
              
                      Thread t2 = new Thread(new Runnable() {
              
                          @Override
                          public void run() {
                              for(int i = 0; i < 5; i++) {
                                  try {
                                      Thread.sleep(3000);
                                  } catch (InterruptedException e) {
                                      // TODO Auto-generated catch block
                                      e.printStackTrace();
                                  }
                                  System.out.println("Thread T2 : "+i);
                              }
                          }
                      });
              
                      Thread t3 = new Thread(new Runnable() {
              
                          @Override
                          public void run() {
                              for(int i = 0; i < 5; i++){
                                  try {
                                      Thread.sleep(3000);
                                  } catch (InterruptedException e) {
                                      // TODO Auto-generated catch block
                                      e.printStackTrace();
                                  }
                                  System.out.println("Thread T3 : "+i);
                              }
                          }
                      });
              
                      t1.start();
                      t2.start();
                      t3.start();
                  }
              }
              

              【讨论】:

                【解决方案12】:

                添加Thread.sleep

                try {
                        Thread.sleep(3000);
                    } catch(InterruptedException ie) {}
                

                【讨论】:

                  【解决方案13】:

                  对于小型应用程序,可以使用 Rohit 提到的 Timer 和 TimerTask,但在 Web 应用程序中,我会使用 Quartz Scheduler 来安排作业并执行此类周期性作业。

                  有关 Quartz 调度,请参阅 tutorials

                  【讨论】:

                    【解决方案14】:
                    public class TimeDelay{
                      public static void main(String args[]) {
                        try {
                          while (true) {
                            System.out.println(new String("Hello world"));
                            Thread.sleep(3 * 1000); // every 3 seconds
                          }
                        } catch (InterruptedException e) {
                          e.printStackTrace();
                        }
                      }
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2013-08-23
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-02-03
                      • 2018-03-11
                      • 2014-01-10
                      • 1970-01-01
                      • 2015-05-04
                      相关资源
                      最近更新 更多