Otrzymuję wyjątek podczas korzystania z Thread.sleep (x) lub wait ()


343

Próbowałem opóźnić - lub uśpić - mój program Java, ale wystąpił błąd.

Nie mogę użyć Thread.sleep(x)lub wait(). Pojawia się ten sam komunikat o błędzie:

niezgłoszony wyjątek java.lang.InterruptedException; musi zostać złapany lub ogłoszony wyrzuceniem.

Czy przed użyciem metod Thread.sleep()lub jest wymagany jakiś krok wait()?


8
To jest popularne. Musi istnieć ogromna liczba osób, które muszą opóźnić swój program Java na kilka sekund. Trudne do wyobrażenia. Oczywiście umieszczenie poprawnego tytułu na poście bardzo by pomogło.
— Robert Harvey

Odpowiedzi:


575

Przed tobą dużo czytania. Od błędów kompilatora po obsługę wyjątków, wątkowanie i przerwy w wątkach. Ale zrobi to, co chcesz:

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

1
dzięki za pomoc, mogłem go uruchomić .. poza tym, jaki jest pożytek z catch (interruptException ex)
— Vincent Low

4
Zobacz odpowiedź Abla. Google for InterruptedException. Krótko mówiąc: wątek można przerwać podczas snu, a jest to pewien wyjątek, który należy wyraźnie rozwiązać.
— Konrad Garus

8
Niektóre odpowiedzi mówią, aby nic nie robić na wyjątku, niektóre mówią, aby rzucić, to mówi interrupt (). Czy ktoś chciałby przedyskutować, co jest właściwe i dlaczego?
— Suma

6
@Suma Istnieje wiele dyskusji na ten temat, w tym sam Stack Overflow. Po prostu go wyszukaj. Za długo na komentarz. Po kilku latach jedyną odpowiedzią, jaką mam, jest: to zależy. Zwykle idealnym rozwiązaniem jest zakończenie tego, co wątek robi z wdziękiem (np. Wycofanie transakcji, przerwanie pętli itp.), Ale to bardzo zależy od kontekstu.
— Konrad Garus

więc niż do czego służy zegar? czy możesz osiągnąć tę samą funkcjonalność za pomocą timera? Przeczytałem dokument w języku Java i wspomniałem o opóźnieniach, ale będąc nowicjuszem z kodem, kończę drugi rok programowania w szkole średniej, nie jestem do końca pewien, czy opóźnienie, o którym mówi, byłoby przydatne tutaj, a nawet właściwa klasa do użycia
— Ungeheuer

195

Jak powiedzieli inni użytkownicy, powinieneś otoczyć rozmowę try{...} catch{...}blokiem. Ale odkąd Java 1.5 została wydana, istnieje klasa TimeUnit, która robi to samo co Thread.sleep (millis), ale jest wygodniejsza. Możesz wybrać jednostkę czasu dla operacji snu.

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
}

Ma także dodatkowe metody: Dokumentacja Oracle TimeUnit


6
Zobacz inne odpowiedzi, na przykład jak otoczyć te połączenia wymaganą try-catchobsługą wyjątków.
— Basil Bourque

2
Nie zapomnij „import java.util.concurrent.TimeUnit;”
— koder


13

Użyj poniższej konstrukcji kodowania do obsługi wyjątków

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

8

Umieść Thread.sleepblok próbny

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


3

Spróbuj tego:

try{

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

8
Czy łapanie Exceptionw Javie nie jest złą praktyką ?
— Michael Dorst

2
Lepiej złap InterruptedException podobnie jak inne odpowiedzi tutaj
— devsaw

6
Nazywa się to „Pokemon Exception Handler” - musisz złapać ich wszystkich.
— James Tayler,

3

Moje sposoby na dodanie opóźnienia do programu Java.

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   
    }
}

Odnosi się to do sekwencyjnego opóźnienia, ale dla opóźnień w pętli patrz Java Delay / Wait .


Pamiętaj, że rażąca autopromocja nie jest tutaj dozwolona. Zobacz ostatni punkt tutaj w Centrum pomocy . Możesz jednak umieścić link w swoim profilu - jest to dozwolone.
— SL Barth - Przywróć Monikę

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
}

na przykład:-

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

Prostszym sposobem oczekiwania jest użycie System.currentTimeMillis(), które zwraca liczbę milisekund od północy 1 stycznia 1970 roku UTC. Na przykład, aby poczekać 5 sekund:

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

W ten sposób nie musisz grzebać w wątkach i wyjątkach. Mam nadzieję że to pomoże!


To zużywa procesor podczas oczekiwania.
— yacc

@yacc To prawda, ale jest prostsze niż używanie wątków i nie zużywa zbyt wiele procesora.
— Sam

0

Użyj java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Śpij przez sekundę lub

TimeUnit.MINUTES.sleep(1);

Śpij przez minutę.

Ponieważ jest to pętla, stanowi to nieodłączny problem - dryf. Za każdym razem, gdy uruchamiasz kod, a następnie śpisz, trochę odpadasz od uruchamiania, powiedzmy, co sekundę. Jeśli jest to problem, nie używaj gosleep .

Dalej, sleep nie jest zbyt elastyczny, jeśli chodzi o kontrolę.

Do uruchamiania zadania co sekundę lub z jednosekundowym opóźnieniem zdecydowanie zalecam [ ScheduledExecutorService] [1] i albo [ scheduleAtFixedRate] [2] albo [scheduleWithFixedDelay ] [3].

Aby uruchomić metodę myTaskco sekundę (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() jest prosty dla początkujących i może być odpowiedni do testów jednostkowych i weryfikacji koncepcji.

Ale proszę NIE używać sleep()do kodu produkcyjnego. Ostateczniesleep() może cię źle ugryźć.

Najlepsza praktyka w przypadku wielowątkowych / wielordzeniowych aplikacji Java do korzystania z koncepcji „wątku oczekiwania”. Funkcja Wait zwalnia wszystkie blokady i monitory utrzymywane przez wątek, co pozwala innym wątkom na uzyskanie tych monitorów i kontynuowanie, gdy wątek śpi spokojnie.

Poniższy kod demonstruje tę 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 realizacja:

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

Alternatywnie, jeśli nie chcesz zajmować się wątkami, wypróbuj tę metodę:

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

Zaczyna się, gdy zadzwonisz, a kończy, gdy upłynie liczba sekund.


7
Zużyłoby to procesor podczas snu. W Thread.sleep () wątek można zaprojektować.
— Vivek Pandey,

jesteś ridi i nie ma wody: D
— M410

17
użytkownik2276378 źle zrozumiał angielski w pytaniu. OP powiedział, że „nie był w stanie spać ani czekać”, który użytkownik2276378 uważał za oznaczający, że nie może z nich korzystać (lub nie mógł ich używać) i dlatego podał prawidłowe rozwiązanie, które nie używało trybu spania lub oczekiwania. Staraj się nie być zbyt surowym Angielski nie jest pierwszym językiem każdego.
— David Newcomb
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.