使一个简单的Java定时器

问题描述 投票:4回答:3

我似乎无法弄清楚如何使一个简单的Java定时器。所有我需要做的仅仅是显示时间,真的。所以,仅仅是一个开始的方法,它会持续计数像0:00,0:01,0:02,等等。我已经看到了这方面的一些其他类似的论坛帖子,但所有的代码是一种复杂,我的水平理解;我有点新到Java。但它不应该是很难做,只是执行这样一个基本功能的计时器?如果有人可以帮助将不胜感激:)

java timer
3个回答
22
投票

这并不难。不过,我要提醒你,我看到的堆栈溢出一些非常困惑的答案,在某些情况下,令人吃惊的糟糕的编码习惯,所以要非常小心。首先让我来回答这个问题。

如果看来,程序员在落实计时器的最大的错误,是认为他们需要的东西,以保持轨道的当前时间。也就是说,他们写某种循环的一个递增的变量每秒或一些这样的傻事。你并不需要编写代码,以跟踪的时间。该功能将System.currentTimeMillis()为你做的,它确实是相当准确的。

定时器代码将涉及两个方面,许多程序员混合起来:

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

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

long startTime = System.currentTimeMillis();

后来,当你要显示的时间量,你只要从当前时间减去此。

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

程序员犯的最大错误就是认为他们需要一个变量来保存当前的时间,然后编写代码来增加该变量每一秒,例如一种叫“elapsedSeconds”他们维护。问题是,你可以安排代码被称为每一秒,但目前还没有确切的时码会被称为保证。如果系统繁忙,该代码可能会比第二颇有几分以后调用。如果系统非常繁忙(例如页面从故障磁盘读取),它实际上可能是几秒钟迟到。它使用了Thread.sleep代码(1000)函数来循环每秒会发现误差随时间而积聚。如果睡眠返回300ms的晚一次,该错误配合到你的是什么时间计算。这一切都是完全不必要的,因为OS具有的功能,告诉你当前时间。

是否在运行此代码的第二每一秒,100次,或每3.572秒上述计算将是准确的。问题的关键是,currentTimeMillis()是时间的准确表示无论何时该代码被称为 - 这是一个重要的考虑因素,因为线程和定时器事件不能保证准确,在特定的时间。

定时器的第二方面是所述显示器的刷新。这将取决于您使用的显示技术。在GUI环境中,你需要安排的油漆事件。你想,显示有望改变的时间之后,这些油漆事件来的权利。然而,这是非常棘手。您可以要求油漆事件,但可能有数百个排队等油漆事件之前你要处理。

一个偷懒的方法做,这是安排每秒10点油漆的事件。由于时间的计算不依赖于代码被称为在特定时间点,并用相同的时间,因为它如果你没关系重新绘制屏幕,​​这种做法或多或少地保证了显示的时间展示中的第二大约1/10的好时机。这似乎有点浪费,因为9次了10年你画什么已经是在屏幕上。

如果您正在使用某种形式(如游戏),这是在刷新屏幕每秒30次的动画编写一个程序,那么你不需要做任何事情。刚刚纳入计时器显示呼叫到你的正常屏幕刷新。

如果油漆事件是昂贵的,或者如果你正在编写一个程序,做终端式输出,可以通过计算时间的剩余量,直到显示将变为优化事件的日程安排:

long elapsedTime = System.currentTimeMillis() - startTime;
long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);

可变timeTillNextDisplayChange认为你需要等待,直到计时器会改变的部分秒的毫秒数。然后,您可以安排一个漆事件在那个时候发生的,可能调用Thread.sleep(timeTillNextDisplayChange)和后寝来做输出。如果你的代码在浏览器中运行,您可以使用此技术在合适的时间来更新页面的DOM。

请注意,没有什么在这个计算显示刷新该效果的定时器本身的精度。该线程可能会从睡眠10ms的恢复后期,甚至是500毫秒晚了,计时器的精度将不受影响。在每一个过程中,我们计算时间从的currentTimeMillis等待,所以被称为晚期有一次以后不会造成显示迟到。

这是关键,一个精确的定时器。不要指望OS打电话给你的日常或当你问它准确地送油漆的事件。通常情况下,当然,拥有现代化的机器,操作系统是非常敏感和准确。这发生在您运行的不是别的不多测试的情况下,和定时器似乎工作。但是,在生产,特殊压力的形势下,你不希望你的计时器“漂流”,因为系统繁忙。


0
投票

您可以使用Timer类从java.util或另一种方式,这是比较复杂的,是线程。计时器也有螺纹的行动,但它是很容易理解的使用它。


0
投票

为了创建你根据自己的需要解释的一个简单的定时器,它很容易编写,一个代码。我已经写了下面的代码,供大家参考。如果你愿意,你可以提高它。

进口java.util.concurrent.TimeUnit中;公共类PerfectTimer {

public static void main(String[] args) throws InterruptedException 
{
    boolean x=true;
    long displayMinutes=0;
    long starttime=System.currentTimeMillis();
    System.out.println("Timer:");
    while(x)
    {
        TimeUnit.SECONDS.sleep(1);
        long timepassed=System.currentTimeMillis()-starttime;
        long secondspassed=timepassed/1000;
        if(secondspassed==60)
        {
            secondspassed=0;
            starttime=System.currentTimeMillis();
        }
        if((secondspassed%60)==0)
        displayMinutes++;

    System.out.println(displayMinutes+"::"+secondspassed);
    }

}

}

© www.soinside.com 2019 - 2024. All rights reserved.