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()?

Vincent Low
źródło
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();
}
Konrad Garus
źródło
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

Aleksander Iwanow
źródło
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
}
Jatin
źródło
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);
}
JoseK
źródło
7

Korzystając z Androida (jedynego razu, kiedy używam Javy), zaleciłbym użycie modułu obsługi zamiast uśpienia wątku.

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);

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

Sindri Þór
źródło
4
To jest dla Androida nie dla Core Java
Ganesh Krishnan
3

Spróbuj tego:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}
SlickJava
źródło
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 .

DRBendanillo
źródło
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);


  }
}
c0der
źródło
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!

Sam
źródło
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");
}
Gavriel Cohen
źródło
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();
        }
    }
}
Valchkou
źródło
-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.

użytkownik2276378
źródło
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