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

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

  • 线程与线程.睡眠
  • 计时器任务
  • 处理程序与后延迟

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

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

谢谢


答案 1

使用计时器有一些缺点

  • 它只创建单个线程来执行任务,如果一个任务运行时间太长,其他任务就会受到影响。
  • 它不处理任务引发的异常,线程只是终止,这会影响其他计划任务,并且它们永远不会运行

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);

答案 2

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

处理程序有两个主要用途:(1) 将消息和可运行项安排在将来的某个时间点执行;以及 (2) 将要在与您自己的线程不同的线程上执行的操作排队。


推荐