Comment faire un retard en Java?

345

J'essaie de faire quelque chose en Java et j'ai besoin de quelque chose pour attendre / retarder pendant quelques secondes dans une boucle while.

while (true) {
    if (i == 3) {
        i = 0;
    }

    ceva[i].setSelected(true);

    // I need to wait here

    ceva[i].setSelected(false);

    // I need to wait here

    i++;
}

Je veux construire un séquenceur pas à pas et je suis nouveau sur Java. Aucune suggestion?

ardb
la source
19
Utilisez Thread.Sleep().
Tiny
2
Pensez à utiliser une minuterie
PeterMmm
2
Quel est le but de l'attente? Attendez-vous qu'un certain événement se produise? Assurez-vous de comprendre ce que fait la méthode sleep ()
artdanil
@Tiny, ce n'est PAS sûr.
Yousha Aleayoub
12
C'est en fait Thread.sleep(<milisecondsToSleep>). Le sne doit pas être capitalisé.
Benjamin

Réponses:

679

Si vous voulez faire une pause, utilisez java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Dormir une seconde ou

TimeUnit.MINUTES.sleep(1);

Dormir une minute.

Comme il s'agit d'une boucle, cela présente un problème inhérent - la dérive. Chaque fois que vous exécutez du code et que vous dormez, vous vous éloignerez un peu de l'exécution, disons, chaque seconde. Si c'est un problème, n'utilisez passleep .

De plus, sleepn'est pas très flexible en matière de contrôle.

Pour exécuter une tâche toutes les secondes ou avec un retard d'une seconde, je recommande fortement a ScheduledExecutorServiceet soit scheduleAtFixedRateou scheduleWithFixedDelay.

Par exemple, pour exécuter la méthode myTasktoutes les secondes (Java 8):

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(App::myTask, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}

Et en Java 7:

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            myTask();
        }
    }, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}
Boris l'araignée
la source
1
@Matthew Moisen Je n'ai pas pu exécuter cet exemple Java 8. Qu'est-ce que App :: exactement? En changeant myTask () en lambda exécutable, cela fonctionne: Runnable myTask = () -> {...};
comfytoday
2
C'est une référence de méthode @comfytoday - je suggère de commencer par la documentation .
Boris the Spider
TimeUnit.SECONDS.wait(1)lance IllegalMonitorStateExceptiondans Java 8.1 build 31 sur Windows 6.3. Au lieu de cela, je peux l'utiliser Thread.sleep(1000)sans essayer / attraper.
John Meyer
1
En Java 8, dans java.util.concurrent.TimeUnit vous obtenez Unhandled exception: java.lang.InterruptedExecutionpour lesleep(1)
Shai Alon
1
Vous devez entourer le TimeUnit.SECONDS.sleep(1);avectry catch
Shai Alon
148

Utilisation Thread.sleep(1000);

1000 est le nombre de millisecondes pendant lequel le programme se mettra en pause.

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}
Anju Aravind
la source
5
N'oubliez pas de consigner l'exception InterruptedException ou vous ne saurez jamais que ce fil a été interrompu.
m0skit0
12
Je suis curieux de savoir ce que Thread.currentThread (). Interrupt (); fait ici.
Brent212
1
voir: "Pourquoi devons-nous à nouveau interrompre le fil?" ici: javaspecialists.eu/archive/Issue056.html
Tristan
6

utilisez ceci:

public static void wait(int ms){
        try
        {
            Thread.sleep(ms);
        }
        catch(InterruptedException ex)
        {
            Thread.currentThread().interrupt();
        }
    }

alors vous pouvez appeler cette méthode n'importe où comme:

        wait(1000);
Hecanet
la source
3

Utiliser TimeUnit.SECONDS.sleep(1);ou Thread.sleep(1000);est une façon acceptable de le faire. Dans les deux cas, vous devez intercepter InterruptedExceptionce qui rend votre code volumineux.Il existe une bibliothèque java Open Source appelée MgntUtils (écrite par moi) qui fournit un utilitaire qui traite déjà à l' InterruptedExceptionintérieur. Donc, votre code ne comprendra qu'une seule ligne:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

Voir le javadoc ici . Vous pouvez accéder à la bibliothèque depuis Maven Central ou depuis Github . L'article expliquant la bibliothèque se trouve ici

Michael Gantman
la source
2
L'utilisation catch (InterruptedException e) { /* empty */ }n'est PAS une solution sensée ici. À tout le moins, vous devez fournir des informations de journal. Pour plus d'informations sur le sujet, voir javaspecialists.eu/archive/Issue056.html
Marco13
3

Utilisez Thread.sleep(100);. L'unité de temps est en millisecondes

Par exemple:

public class SleepMessages {
    public static void main(String args[])
        throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}
Bachan Joseph
la source
1

Je sais que c'est un très ancien article, mais cela peut aider quelqu'un: vous pouvez créer une méthode, donc chaque fois que vous devez faire une pause, vous pouvez taper pause(1000)ou toute autre valeur en millisecondes:

public static void pause(int ms) {
    try {
        Thread.sleep(ms);
    } catch (InterruptedException e) {
        System.err.format("IOException: %s%n", e);
    }
}

Ceci est inséré juste au-dessus de public static void main(String[] args), à l'intérieur de la classe. Ensuite, pour appeler la méthode, tapez pause(ms)mais remplacez mspar le nombre de millisecondes à mettre en pause. De cette façon, vous n'avez pas à insérer l'intégralité de l'instruction try-catch chaque fois que vous souhaitez faire une pause.

dominic03
la source