每 X 秒打印一次“hello world”
Posted
技术标签:
【中文标题】每 X 秒打印一次“hello world”【英文标题】:Print "hello world" every X seconds 【发布时间】: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 秒打印一次?
【问题讨论】:
虽然以下答案显然应该回答您的问题,但您还应该注意,您这样做的方式会导致每台机器上的时间间隔不同。取决于它运行编译器的速度。 Calling a function every 10 minutes的可能重复 【参考方案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 = () -> /*code */ ;
,这样更漂亮;)【参考方案2】:
您还可以查看Timer
和TimerTask
类,您可以使用它们来安排您的任务每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-paramschedule
方法将在指定的延迟后执行一次。需要使用 3 参数 schedule
或 scheduleAtFixedRate
。
@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.Timer
和TimerTask
的计时器。见下文:
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.Timer
和Timer#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();
【讨论】:
以上是关于每 X 秒打印一次“hello world”的主要内容,如果未能解决你的问题,请参考以下文章