我想创建一个永不停止的线程。它每秒都会获得系统时间并在控制台上显示。这就是我到目前为止所做的:
public class Test implements Runnable {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}
我想避免使用循环。
答案 0 :(得分:2)
使用while(true)
和TimeUnit.SECONDS.sleep
是可能的,但这是不好的做法(正如你可以从这篇帖子中的大量下线看到的那样)。 This SO answer给出了原因:
还有其他人。
实现此目标的基本方法是使用java.util.Timer
,不要与javax.swing.Timer
混淆:
final Timer timer = new Timer("MyTimer");
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, TimeUnit.SECONDS.toMillis(1));
您需要调用timer.cancel()
来停止计时器 - 因为计时器正在运行非守护程序线程,程序将不会退出,直到完成为止。
一种更高级的方法,允许将多个任务安排在ScheduledExecutorService
的池上以不同的时间间隔运行。这允许你scheduleAtFixedRate
每秒运行一个任务(无论运行多长时间,即 start 时间之间的差距始终相同)或scheduleWithFixedDelay
以一秒的间隔运行任务(即一次运行结束与下一次运行结束之间的差距始终相同)。
例如:
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final ScheduledFuture<?> handle = executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, 1, TimeUnit.SECONDS);
要取消您要拨打handle.cancel(false)
的特定任务(由于中断无效)并停止executorService
,您可以致电executorService.shutdown()
,之后您可能需要添加executorService.awaitTermination(1, TimeUnit.DAYS)
1}}等待所有任务完成。
修改强>
评论这可以在java 8中使用lambda更简洁地完成吗? (不是lambdas的专家)
第一个例子,没有。 Timer
需要TimerTask
,这是abstract class
而不是@FunctionalInterface
所以lambda是不可能的。在第二种情况下,确定:
final ScheduledFuture<?> handle = executorService.
scheduleAtFixedRate(() -> System.out.println(System.currentTimeMillis()), 0, 1, TimeUnit.SECONDS);