Ich bekomme eine Ausnahme, wenn ich Thread.sleep (x) oder wait () verwende.


343

Ich habe versucht, mein Java-Programm zu verzögern oder in den Ruhezustand zu versetzen, aber es tritt ein Fehler auf.

Ich kann Thread.sleep(x)oder nicht verwenden wait(). Die gleiche Fehlermeldung wird angezeigt:

nicht gemeldete Ausnahme java.lang.InterruptedException; muss gefangen oder zum Werfen erklärt werden.

Ist vor der Verwendung der Methoden Thread.sleep()oder ein Schritt erforderlich wait()?


8
Nun, das ist beliebt. Es muss eine enorme Anzahl von Menschen geben, die ihr Java-Programm um einige Sekunden verzögern müssen. Schwer vorstellbar. Natürlich würde es immens helfen, den richtigen Titel auf den Beitrag zu setzen.
Robert Harvey

Antworten:


575

Sie haben viel zu lesen. Von Compilerfehlern über Ausnahmebehandlung, Threading und Threadunterbrechungen. Aber das wird machen was du willst:

try {
    Thread.sleep(1000);                 //1000 milliseconds is one second.
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}

1
Vielen Dank für Ihre Hilfe, ich kann es ausführen. Außerdem, was ist die Verwendung für catch (InterruptedException Ex)
Vincent Low

4
Siehe Antwort von Abel. Google für InterruptedException. Um es kurz zu machen: Der Thread kann im Schlaf unterbrochen werden, und dies ist eine Art Ausnahme, die explizit behandelt werden muss.
Konrad Garus

8
Einige Antworten sagen, dass sie nichts für die Ausnahme tun sollen, andere sagen, dass sie werfen sollen, dies sagt, dass sie unterbrechen sollen (). Würde jemand gerne darüber diskutieren, was angemessen ist und warum?
Suma

6
@Suma Es gibt viele Diskussionen darüber, einschließlich Stack Overflow selbst. Suche einfach danach. Zu lang für einen Kommentar. Nach ein paar Jahren ist die einzige Antwort, die ich habe: Es kommt darauf an. Normalerweise besteht die ideale Lösung darin, alles zu beenden, was der Thread ordnungsgemäß ausführt (z. B. diese Transaktion zurücksetzen, eine Schleife unterbrechen usw.), aber das ist sehr kontextabhängig.
Konrad Garus

Also, wofür ist ein Timer? Könnten Sie die gleiche Funktionalität mit einem Timer erreichen? Ich habe das Java-Dokument gelesen und es erwähnte etwas über Verzögerungen, aber da ich ein Neuling mit Code bin, bin ich kurz davor, mein zweites Jahr der High-School-Programmierung zu beenden. Ich bin mir nicht ganz sicher, ob die Verzögerung, über die es spricht, hier nützlich sein würde, oder sogar die richtige Klasse zu verwenden
Ungeheuer

195

Wie andere Benutzer bereits gesagt haben, sollten Sie Ihren Anruf mit einem try{...} catch{...}Block umgeben. Seit der Veröffentlichung von Java 1.5 gibt es jedoch eine TimeUnit-Klasse, die das Gleiche wie Thread.sleep (Millis) tut, jedoch praktischer ist. Sie können die Zeiteinheit für den Schlafbetrieb auswählen.

try {
    TimeUnit.NANOSECONDS.sleep(100);
    TimeUnit.MICROSECONDS.sleep(100);
    TimeUnit.MILLISECONDS.sleep(100);
    TimeUnit.SECONDS.sleep(100);
    TimeUnit.MINUTES.sleep(100);
    TimeUnit.HOURS.sleep(100);
    TimeUnit.DAYS.sleep(100);
} catch (InterruptedException e) {
    //Handle exception
}

Außerdem gibt es zusätzliche Methoden: TimeUnit Oracle Documentation


6
Weitere Antworten finden Sie beispielsweise, wie Sie diese Aufrufe mit der erforderlichen try-catchAusnahmebehandlung umgeben.
Basil Bourque

2
Vergessen Sie nicht "import java.util.concurrent.TimeUnit;"
Codierer


13

Verwenden Sie das folgende Codierungskonstrukt, um Ausnahmen zu behandeln

try {
  Thread.sleep(1000);
} catch (InterruptedException ie) {
    //Handle exception
}

8

Legen Sie Ihre Thread.sleepin einen Try-Catch-Block

try {
    //thread to sleep for the specified number of milliseconds
    Thread.sleep(100);
} catch ( java.lang.InterruptedException ie) {
    System.out.println(ie);
}

7

Bei Verwendung von Android (das einzige Mal, wenn ich Java verwende) würde ich empfehlen, einen Handler zu verwenden, anstatt den Thread in den Ruhezustand zu versetzen.

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "I've waited for two hole seconds to show this!");

        }
    }, 2000);

Referenz: http://developer.android.com/reference/android/os/Handler.html


4
Dies ist für Android nicht für Core Java
Ganesh Krishnan

3

Versuche dies:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}

8
Ist es nicht eine schlechte Praxis, Exceptionin Java zu fangen ?
Michael Dorst

2
Fangen Sie besser InterruptedException wie die anderen Antworten hier
devsaw

5
Dies wird als "Pokemon Exception Handler" bezeichnet - ich muss sie alle fangen.
James Tayler

3

Meine Möglichkeiten, einem Java-Programm eine Verzögerung hinzuzufügen.

public void pause1(long sleeptime) {
    try {
        Thread.sleep(sleeptime);
    } catch (InterruptedException ex) {
        //ToCatchOrNot
    }
}

public void pause2(long sleeptime) {
    Object obj = new Object();
    if (sleeptime > 0) {
        synchronized (obj) {
            try {
                obj.wait(sleeptime);
            } catch (InterruptedException ex) {
                //ToCatchOrNot
            }
        }
    }
}
public void pause3(long sleeptime) {
    expectedtime = System.currentTimeMillis() + sleeptime;
    while (System.currentTimeMillis() < expectedtime) {
        //Empty Loop   
    }
}

Dies gilt für sequentielle Verzögerungen. Schleifenverzögerungen finden Sie unter Java Delay / Wait .


Bitte beachten Sie, dass eine offensichtliche Eigenwerbung hier nicht erlaubt ist. Siehe den letzten Punkt hier in der Hilfe . Sie können den Link jedoch in Ihr Profil einfügen - das ist erlaubt.
SL Barth - Stellen Sie Monica

3
public static void main(String[] args) throws InterruptedException {
  //type code


  short z=1000;
  Thread.sleep(z);/*will provide 1 second delay. alter data type of z or value of z for longer delays required */

  //type code
}

z.B:-

class TypeCasting {

  public static void main(String[] args) throws InterruptedException {
    short f = 1;
    int a = 123687889;
    short b = 2;
    long c = 4567;
    long d=45;
    short z=1000;
    System.out.println("Value of a,b and c are\n" + a + "\n" + b + "\n" + c + "respectively");
    c = a;
    b = (short) c;
    System.out.println("Typecasting...........");
    Thread.sleep(z);
    System.out.println("Value of B after Typecasting" + b);
    System.out.println("Value of A is" + a);


  }
}

0

Eine einfachere Möglichkeit zu warten ist die Verwendung System.currentTimeMillis(), die die Anzahl der Millisekunden seit Mitternacht am 1. Januar 1970 UTC zurückgibt. Zum Beispiel, um 5 Sekunden zu warten:

public static void main(String[] args) {
    //some code
    long original = System.currentTimeMillis();
    while (true) {
        if (System.currentTimeMillis - original >= 5000) {
            break;
        }
    }
    //more code after waiting
}

Auf diese Weise müssen Sie nicht mit Threads und Ausnahmen herumspielen. Hoffe das hilft!


Dies verbraucht während des Wartens CPU.
Yacc

@yacc Dies ist wahr, aber es ist einfacher als die Verwendung von Threads und verwendet nicht zu viel CPU.
Sam

0

Verwendung java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Schlaf für eine Sekunde oder

TimeUnit.MINUTES.sleep(1);

Schlaf eine Minute.

Da dies eine Schleife ist, stellt dies ein inhärentes Problem dar - Drift. Jedes Mal, wenn Sie Code ausführen und dann schlafen, werden Sie beispielsweise jede Sekunde ein wenig vom Laufen abweichen. Wenn dies ein Problem ist, verwenden Sie es nicht sleep.

Darüber hinaus sleepist nicht sehr flexibel, wenn es um Kontrolle geht.

Um eine Aufgabe jede Sekunde oder mit einer Verzögerung von einer Sekunde auszuführen, würde ich dringend eine [ ScheduledExecutorService] [1] und entweder [ scheduleAtFixedRate] [2] oder [ scheduleWithFixedDelay] [3] empfehlen .

So führen Sie die Methode myTaskjede Sekunde aus (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");
}

0

Thread.sleep() ist für Anfänger einfach und eignet sich möglicherweise für Unit-Tests und Proofs of Concept.

Aber bitte NICHT verwenden sleep()für die Produktion Code. Schließlich sleep()kann man schlecht beißen.

Best Practice für Multithread- / Multicore-Java-Anwendungen zur Verwendung des "Thread Wait" -Konzepts. Wait gibt alle Sperren und Monitore frei, die vom Thread gehalten werden, sodass andere Threads diese Monitore erfassen und fortfahren können, während Ihr Thread ruhig schläft.

Der folgende Code demonstriert diese Technik:

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
       DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
       d.delay(500);
       System.out.println("half second after:"+ new Date());
       d.delay(1, TimeUnit.MINUTES); 
       System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil Implementierung:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param durationInMillis the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();

        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}

-2

Wenn Sie sich nicht mit Threads befassen möchten, versuchen Sie alternativ diese Methode:

public static void pause(int seconds){
    Date start = new Date();
    Date end = new Date();
    while(end.getTime() - start.getTime() < seconds * 1000){
        end = new Date();
    }
}

Es beginnt, wenn Sie es aufrufen, und endet, wenn die Anzahl der Sekunden vergangen ist.


7
Dies würde während der Ruhezeit CPU verbrauchen. Auf Thread.sleep () kann der Thread deaktiviert werden.
Vivek Pandey

Sie sind Ridi und es gibt kein Wasser: D
M410

17
user2276378 hatte das Englisch der Frage falsch verstanden. OP sagte, er sei "nicht in der Lage, Schlaf oder Wartezeit zu verwenden", was Benutzer 2276378 bedeutete, dass er sie nicht verwenden konnte (oder nicht verwenden durfte), und lieferte daher eine gültige Lösung, die weder Schlaf noch Wartezeit verwendete. Versuche nicht zu hart zu sein Englisch ist nicht jedermanns Muttersprache.
David Newcomb
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.