64

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

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

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

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

谢谢

4

4 回答 4

74

使用 Timer 有一些缺点

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

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);
于 2013-09-04T05:34:42.757 回答
7

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

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

于 2013-09-04T05:34:39.850 回答
1

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

于 2013-09-04T04:47:57.673 回答
-13

使用 TimerTask 进行循环动作是更好的选择。推荐

于 2013-09-04T04:33:48.863 回答