web-dev-qa-db-fra.com

TimerTask vs Thread.sleep vs Handler postDelayed - la fonction d'appel la plus précise toutes les N millisecondes?

Quelle est la façon la plus précise d'appeler une fonction toutes les N millisecondes?

  • Enfilez avec Thread.sleep
  • TimerTask
  • Gestionnaire avec postDelayed

J'ai modifié cet exemple en utilisant Thread.sleep et ce n'est pas très précis.

Je développe une application musicale qui jouera des sons à un BPM donné. Je comprends qu'il est impossible de créer un métronome entièrement précis et je n'ai pas besoin de le faire - je cherche juste à trouver la meilleure façon de le faire.

Merci

54
fxfuture

L'utilisation de la minuterie présente certains inconvénients

  • Il ne crée qu'un seul thread pour exécuter les tâches et si une tâche prend trop de temps à s'exécuter, d'autres tâches en souffrent.
  • Il ne gère pas les exceptions levées par les tâches et le thread se termine, ce qui affecte les autres tâches planifiées et elles ne sont jamais exécutées

ScheduledThreadPoolExecutor traite correctement tous ces problèmes et il n'est pas logique d'utiliser Timer .. Il existe deux méthodes qui pourraient être utiles dans votre cas .. ScheduleAtFixedRate (...) et 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);
59
Amol Sonawane

Sur Android vous pouvez créer un fil avec son propre gestionnaire/file d'attente de messages. C'est assez précis. Lorsque vous voyez le gestionnaire documentation vous pouvez voir qu'il a été conçu pour cela.

Il existe deux utilisations principales d'un gestionnaire: (1) pour planifier les messages et les runnables à exécuter à un moment donné dans le futur; et (2) pour mettre en file d'attente une action à effectuer sur un thread différent du vôtre.

7
mleczey

Ils sont tous identiques en termes de précision. Java la précision de synchronisation dépend de la précision et de l'exactitude des temporisateurs et des planificateurs du système et n'est pas garantie. Voir Thread.sleep et API Object.wait.

1
Evgeniy Dorofeev