我正在开发一个Java程序,要求我安排定期执行任务。但限制是我不能使用线程。
我遇到过Timer和TimerTask,但我不确定他们是否创建了线程..
有没有办法在不使用线程的情况下完成此操作?
提前致谢。
答案 0 :(得分:2)
所有Java计时器,甚至是Swing Timer,都使用一个单独的线程来等待并在适当的时间触发事件。
如果程序必须定期执行某些操作,但无法启动新线程,那么主线程必须执行此操作。
但是,可以吗?它在做什么呢?
如果主线程处于空闲状态,您可以计算下一次事件之前的时间量,并计算sleep之前的时间。
答案 1 :(得分:0)
这取决于您的应用程序设计。一种可能的方法是将您的应用程序设计为要执行的任务。并使用Cron作业(类Unix计算机操作系统中基于时间的作业调度程序)启动它。
答案 2 :(得分:0)
您可以尝试使用Quartz调度程序。虽然它在内部使用线程池。它稳定而有效。
答案 3 :(得分:0)
Thread.sleep
如the answer by Andreas所述,您可以重复睡眠当前线程以执行重复任务。我理解你的情况是家庭作业课程中的指定要求,不使用线程。我假设分配的目的是不使用其他线程。您执行的代码始终在一个线程中。每个Java应用程序都以JVM提供的初始线程开始。
但你应该知道,在实际工作中,“没有更多线程”的要求是愚蠢的;线程的目的是在不同的时间框架上执行任务。因此,对于实际工作,我会推荐其他更优雅,更灵活,更强大的方法(搜索Java Executors和ScheduledExecutorService
)。
但是对于你的作业,Thread
类确实提供了一个静态方法sleep
,用于使当前线程进入休眠状态。
Instant
是UTC中时间轴上的一个时刻,分辨率高达纳秒。 Java 8及更高版本中内置的java.time框架的一部分。可用于Java 6和Java 6的后端口7和Android。
TimeUnit
枚举使转换为毫秒自我记录。
请注意,休眠线程可能被另一个线程或JVM唤醒。发生这种情况时,唤醒的线程会遇到InterruptedException
。
long millisToSleep = java.util.concurrent.TimeUnit.MINUTES.toMillis ( 5 );
Instant now = Instant.now ();
Instant limit = now.plus ( 1 , ChronoUnit.HOURS );
while ( Instant.now ().isBefore ( limit ) ) {
System.out.println ( "Doing some stuff at " + Instant.now () );
// … do some stuff.
System.out.println ( "Going to sleep for " + millisToSleep + " milliseconds." );
try {
Thread.sleep ( millisToSleep ); // I do not recommend this approach, but it works. Better to use a 'ScheduledExecutorService'.
} catch ( InterruptedException ex ) {
System.out.println ( "This thread’s sleep was rudely interrupted at " + Instant.now () + ". Stopping any further work." );
break; // Bail out of the 'while' loop.
}
}