线程是否足够可靠以计算秒数?

时间:2014-03-18 11:02:58

标签: java android multithreading date time

我正在创建一个Android应用程序,在某些活动中显示一个小时分钟和秒钟的计时器。由于秒值将每秒更新一次,我正在考虑制作一个1000毫秒睡眠的线程,在每个周期后它将添加1到秒并更新文本视图。因此,它将计算分钟和小时并更新相应的文本视图。

但是我有一个疑问,线程是否足够可靠以完成这样的任务,还是应该使用内置的库函数来在每个周期后获得几秒钟?如果我完全依赖线程计算时间,我有点担心我的计时器不同步。

9 个答案:

答案 0 :(得分:8)

睡眠不够好。

睡眠将暂停线程至少指定的时间段,但实际的睡眠时间可能比指定的时间长。

答案 1 :(得分:7)

使用HandlerHere这是一篇非常详细的文章。

long startTime = 0;

Handler timerHandler = new Handler();

Runnable timerRunnable = new Runnable() {
    @Override
    public void run() {
        long millis = System.currentTimeMillis() - startTime;
        int seconds = (int) Math.round(diff / ((double)1000));
        int minutes = (int) Math.round(seconds / ((double)60));
        seconds = seconds % 60;

        // Use the seconds

        timerHandler.postDelayed(this, 500);
    }
};

启动计时器 -

startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);

停止计时器 -

timerHandler.removeCallbacks(timerRunnable);

暂停 -

timerHandler.removeCallbacks(timerRunnable);

答案 2 :(得分:3)

延迟1000毫秒的睡眠是不好的选择,因为总是存在抖动,并且在执行例程时也会花费一些CPU时间。

我建议从ScheduledExecutorService.scheduleAtFixedRate方法中获利,这将以固定费率调用您的实施。

答案 3 :(得分:2)

根据您所描述的逻辑,您确实会得到一些漂移,即每个周期可能会产生的小错误将会增加很多。虽然很容易补救。

保持变量保持最后一次触发的时间。完成睡眠后,将1000添加到最后一个触发时间,计算剩余时间直到该时间,然后再睡眠。通过这种方式,您可能偶尔会遇到延迟触发,但很快就会得到纠正。

答案 4 :(得分:2)

永远不应该依赖线程sleep。它不保证确切的时差。

我建议您使用计时器任务。它易于使用且非常可靠。

祝你好运。

答案 5 :(得分:1)

  

但我心中有一个疑问,线程是否足够可靠   完成这样的任务

不,他们不是。

您可以使用线程更新时钟显示,但您应该再次阅读System.currentTimeMillis()(或类似)。

答案 6 :(得分:1)

如果您说睡眠1秒钟,线程将休眠1秒钟,线程唤醒时指令发生的实际时间取决于其他因素,例如操作系统和CPU的线程调度。它不大可能产生巨大的影响,但为什么不简单地跟踪实际的时间戳,以便确切地知道已经过了多少时间,并且如果有任何差异则相应地更正?

您可以使用像System.currentTimeMillis()

这样简单的内容

答案 7 :(得分:1)

在android中使用sleep的简单线程是不可能的。只需使用runnable thread。

当您需要根据秒数更新textview时启动此功能。在这个我尝试了分钟,秒和毫秒。

看看吧。

创建一个textview,并使用以下runnable设置文本。

 private Runnable updateTimerThread = new Runnable() {

        public void run() {

            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

            updatedTime = timeSwapBuff + timeInMilliseconds;

            int secs = (int) (updatedTime / 1000);
            int mins = secs / 60;
            secs = secs % 60;
            int milliseconds = (int) (updatedTime % 1000);
            t1.setText("" + mins + ":"
                    + String.format("%02d", secs) + ":"
                    + String.format("%03d", milliseconds));
            customHandler.postDelayed(this, 0);
        }

    };

答案 8 :(得分:1)

正如其他人所指出的那样,sleep(millis)只保证至少的睡眠时间为毫秒 - 这意味着如果你使用1000而不是偏移它将是落后了。

与偏移量一起使用:

long last = System.currentTimeMillis();
while (true) {
   long current = System.currentTimeMillis();
   Thread.sleep(last-current);
   last = current;
   incrementSeconds();
}