web-dev-qa-db-fra.com

Java - alternative à thread.sleep

J'ai l'obligation de suspendre une boucle while pendant un nombre spécifique de millisecondes. J'ai essayé d'utiliser Thread.sleep (durée) mais ce n'est pas précis, en particulier dans un scénario en boucle. La précision en millisecondes est importante dans mon programme.

Voici l'algorithme où je ne veux pas revenir en arrière pour vérifier l'état jusqu'à ce que expectedElapsedTime soit passé. 

while (condition) {
    time = System.currentTimeMillis();
    //do something
    if (elapsedTime(time) < expectedElapsedTime) ) {
        pause the loop  // NEED SUBSTITUTE FOR Thread.sleep()
    }
    // Alternative that I have tried but not giving good results is 
    while ((elapsedTime(time) < expectedElapsedTime)) {
        //do nothing
    }
}

long elapsedTime(long time) {
   long diff = System.currentTimeMillis() - time;
   return diff;
}
16
user1189747

Essayez un ScheduledThreadPoolExecutor . Il est supposé donner des résultats de chronométrage plus fiables. 

9
Bill

Qu'attendez-vous? 

Si vous mettez en veille, une fois que votre processus sera à nouveau exécutable, il devra attendre que le planificateur de thread le planifie à nouveau. 

Je veux dire que si vous vous mettez en veille pendant 50 secondes, cela ne signifie pas que votre processus s'exécutera dans exactement 50 secondes.Parce qu'il se réveille et qu'il est exécutable, il devra attendre d'être planifié pour que le processeur prenne du temps supplémentaire plus le temps que vous avez programmé. avoir pour le changement de contexte. 

Vous ne pouvez rien faire pour le contrôler, vous ne pouvez donc pas avoir la précision que vous dites. 

Pour votre cas, je suggérerais plutôt une boucle en rotation. 

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}
8
Cratylus

Java n’est pas un système temps réel, vous ne pouvez pas faire filer et revenir avec un calendrier aussi serré. Pour planifier l'exécution de votre programme en millisecondes, vous devez utiliser une plate-forme différente, telle que simpleRTJ ou extension Java Real-Time

5
jprusakova

Le retard est susceptible d'être choisi arbitrairement, alors je me demanderais si vous avez besoin d'un intervalle de temps réel. 

Si vous avez besoin de temps de lecture, vous devez être occupé et attendre que le temps soit écoulé. Abandonner le processeur signifie que vous ne pouvez pas garantir que vous le récupérerez exactement quand vous le souhaitez.

2
Peter Lawrey

Vous pouvez implémenter le mécanisme wait/notify et déléguer à un autre thread la responsabilité de notifier l'autre thread en attente, indiquant que le délai est écoulé et qu'il peut aller de l'avant ...

Par exemple, lorsque le threadA doit attendre un certain temps, vous pouvez le mettre en attente et lancer une tâche du minuteur qui, après un certain temps (appel), notifie et réveille le ThreadA qui continue, ce qui peut être une alternative.

1
aleroot

La solution consiste à utiliser un gestionnaire exécutable et à utiliser la méthode 'postDelayed'. Exemple:

new Handler().postDelayed(new Runnable() {
public void run () {
    // Do delayed stuff!
}
}, 5000L); //5 seconds delay 

https://stackoverflow.com/a/21680858

1
Android Freaks

Si vous voulez être précis avec les sons, utilisez un séquenceur et définissez le tempo dans BPM: Sequencer.setTempoInBPM (120); 

1
user1938065

N'oubliez pas les pauses du ramasse-miettes. Il peut battre tous vos plans

0
user2737635