用Java创建一个简单的计时器

Nad*_*dim 4 java timer

我似乎无法弄清楚如何在java中创建一个简单的计时器.我需要做的只是显示时间,真的.所以只是一个开始的方法,它一直在计数,如0:00,0:01,0:02等.我已经看到了一些其他类似的论坛帖子,但所有的代码有点复杂的我的水平理解; 我是java的新手.但是,制作一个只执行这种基本功能的计时器并不难吗?如果有人可以帮助它将不胜感激:)

Agi*_*Pro 22

这并不困难.但是,我会提醒你,我已经看到了一些关于堆栈溢出的非常混乱的答案,在某些情况下编码习惯非常糟糕,所以要非常小心.首先让我回答这个问题.

如果看起来是程序员在实现计时器时犯的最大错误,那就是认为他们需要一些东西来跟踪当前时间.也就是说,他们编写某种循环,每秒递增一个变量或者一些如此愚蠢的东西.您无需编写代码来跟踪时间.该功能System.currentTimeMillis()将为您完成,并且它可以非常准确地完成.

定时器代码将涉及许多程序员混淆的两个方面:

  1. 计算时间
  2. 刷新显示

计算显示时间所需要做的就是记录计时器启动的时间:

long startTime = System.currentTimeMillis();
Run Code Online (Sandbox Code Playgroud)

稍后,当您想要显示时间量时,您只需从当前时间中减去它.

long elapsedTime = System.currentTimeMillis() - startTime;
long elapsedSeconds = elapsedTime / 1000;
long secondsDisplay = elapsedSeconds % 60;
long elapsedMinutes = elapsedSeconds / 60;
//put here code to format and display the values
Run Code Online (Sandbox Code Playgroud)

程序员犯的最大错误就是认为他们需要一个变量来保持当前时间,然后编写代码来每秒递增该变量,例如他们维护的称为"elapsedSeconds"的东西.问题是您可以安排每秒调用代码,但不能保证何时调用该代码.如果系统繁忙,那么该代码可能会比第二个稍晚调用.如果系统非常繁忙(例如从故障磁盘中获取页面),实际上可能会延迟几秒钟.使用Thread.sleep(1000)函数每秒循环的代码将发现错误随着时间的推移而累积.如果睡眠一次返回300毫秒,则该错误会在计算时间时复杂化.这完全没必要,因为操作系统具有告诉您当前时间的功能.

无论您是每秒运行此代码,每秒运行100次,还是每3.572秒执行一次,上述计算将是准确的.关键是currentTimeMillis()无论何时调用此代码,都是时间的准确表示 - 这是一个重要的考虑因素,因为线程和计时器事件不能保证在特定时间是准确的.

计时器的第二个方面是刷新显示器.这取决于您使用的技术.在GUI环境中,您需要安排绘制事件.您希望这些绘制事件在显示器预期更改之后立即生效.但是,它很棘手.您可以申请油漆事件,但可能有数百个其他油漆事件排队等待您的事件处理.

一种懒惰的方法是每秒安排10个绘制事件.因为时间的计算不依赖于在特定时间点调用的代码,并且因为如果您在同一时间重新绘制屏幕并不重要,这种方法或多或少地保证了显示的时间将是在大约1/10秒内显示正确的时间.这看起来有点浪费,因为10次中有9次你正在绘制屏幕上已有的内容.

如果你正在编写一个带有某种类型动画的程序(比如一个游戏),它每秒刷新一次屏幕30次,那么你就什么都不做了.只需将计时器显示调用合并到常规屏幕刷新中即可.

如果绘制事件很昂贵,或者您正在编写执行终端式输出的程序,则可以通过计算显示将更改之前剩余的时间量来优化事件的计划:

long elapsedTime = System.currentTimeMillis() - startTime;
long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);
Run Code Online (Sandbox Code Playgroud)

变量timeTillNextDisplayChange保存您需要等待的秒数,直到计时器的秒部分发生变化.然后,您可以安排在此时发生的绘制事件,可能调用Thread.sleep(timeTillNextDisplayChange)以及在睡眠后执行输出.如果您的代码在浏览器中运行,则可以使用此技术在适当的时间更新页面DOM.

请注意,此计算显示刷新中没有任何内容会影响计时器本身的准确性.线程可能会晚10毫秒,甚至晚500毫秒从睡眠状态返回,并且计时器的准确性不会受到影响.在每次传递时,我们计算从currentTimeMillis等待的时间,因此一次调用迟到不会导致以后的显示延迟.

这是准确计时器的关键.不要指望操作系统调用您的例程或在您要求时准确发送绘图事件.通常,当然,对于现代机器,操作系统具有显着的响应性和准确性.这种情况发生在你没有运行太多其他东西的测试环境中,并且计时器似乎有效.但是,在生产中,在极少的压力情况下,你不希望你的计时器"漂移",因为系统很忙.