Java TimerTask vs Thread.sleep vs Handler postDelayed - 每 N 毫秒调用一次函数最准确?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18605403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:26:34  来源:igfitidea点击:

TimerTask vs Thread.sleep vs Handler postDelayed - most accurate to call function every N milliseconds?

javaandroidmultithreadinghandlertimertask

提问by fxfuture

What is the most accurate way to call a function every N milliseconds?

每 N 毫秒调用一个函数的最准确方法是什么?

  • Thread with Thread.sleep
  • TimerTask
  • Handler with postDelayed
  • 线程与 Thread.sleep
  • 定时器任务
  • 带有 postDelayed 的处理程序

I modified this exampleusing Thread.sleep and it's not very accurate.

我使用 Thread.sleep修改了这个例子,它不是很准确。

I'm developing a music app that will play sounds at a given BPM. I understand it's impossible to create an entirely accurate metronome and I don't need to - just looking to find the best way to do this.

我正在开发一个音乐应用程序,它将以给定的 BPM 播放声音。我知道创建一个完全准确的节拍器是不可能的,我不需要 - 只是想找到最好的方法来做到这一点。

Thanks

谢谢

采纳答案by Amol Sonawane

There are some disadvantages of using Timer

使用 Timer 有一些缺点

  • It creates only single thread to execute the tasks and if a task takes too long to run, other tasks suffer.
  • It does not handle exceptions thrown by tasks and thread just terminates, which affects other scheduled tasks and they are never run
  • 它只创建一个线程来执行任务,如果一个任务运行时间太长,其他任务就会受到影响。
  • 它不处理任务抛出的异常,线程只是终止,这会影响其他计划任务并且它们永远不会运行

ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case.. scheduleAtFixedRate(...) and scheduleWithFixedDelay(..)

ScheduledThreadPoolExecutor 可以正确处理所有这些问题,使用 Timer 没有意义.. 有两种方法可用于您的情况.. scheduleAtFixedRate(...) 和 scheduleWithFixedDelay(..)

class MyTask implements Runnable {

  @Override
  public void run() {
    System.out.println("Hello world");
  } 
}

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);

回答by Isaiah

Using TimerTask for the loop action is the better one. Recommend

将 TimerTask 用于循环操作是更好的选择。推荐

回答by Evgeniy Dorofeev

They are all the same precision-wise. Java timing precision is subject to the precision and accuracy of system timers and schedulers and is not guaranteed. See Thread.sleep and Object.wait API.

它们在精度方面都是相同的。Java 计时精度受制于系统计时器和调度程序的精度和准确度,无法保证。请参阅 Thread.sleep 和 Object.wait API。

回答by mleczey

On Android you can create Thread with it's own Handler/Message Queue. It's quite accurate. When you see Handler documentationyou can see, that it was designed for that.

在 Android 上,您可以使用它自己的处理程序/消息队列创建线程。这是相当准确的。当您看到 Handler文档时,您会发现它是为此而设计的。

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future;and (2) to enqueue an action to be performed on a different thread than your own.

Handler 有两个主要用途:(1) 安排消息和可运行对象在将来的某个时间点执行;(2) 将要在与您自己的线程不同的线程上执行的操作排入队列。