Ottengo un'eccezione quando utilizzo Thread.sleep (x) o wait ()


343

Ho provato a ritardare - o mettere a dormire - il mio programma Java, ma si verifica un errore.

Non riesco a usare Thread.sleep(x)o wait(). Viene visualizzato lo stesso messaggio di errore:

eccezione non dichiarata java.lang.InterruptedException; deve essere catturato o dichiarato lanciato.

È necessario un passaggio prima di utilizzare i metodi Thread.sleep()o wait()?


8
Bene, questo è popolare. Ci deve essere un numero enorme di persone che devono ritardare il loro programma Java per alcuni secondi. Difficile da immaginare. Naturalmente, inserire il titolo corretto sul post sarebbe di grande aiuto.
Robert Harvey,

Risposte:


575

Hai molte letture davanti a te. Dagli errori del compilatore attraverso la gestione delle eccezioni, il threading e le interruzioni del thread. Ma questo farà quello che vuoi:

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

1
grazie per il vostro aiuto, sono in grado di eseguirlo .. a parte, a che serve la cattura (interrottoException ex)
vincent low

4
Vedi la risposta di Abele. Google per InterruptedException. Per farla breve: il thread può essere interrotto durante il sonno, e questa è una sorta di eccezione che deve essere gestita in modo esplicito.
Konrad Garus,

8
Alcune risposte dicono di non fare nulla sull'eccezione, alcune dicono di lanciare, questo dice di interrompere (). Qualcuno vorrebbe discutere quale è appropriato e perché?
Suma,

6
@Suma Ci sono molte discussioni al riguardo, incluso Stack Overflow stesso. Basta cercarlo. Troppo a lungo per un commento. Dopo qualche anno, l'unica risposta che ho è: dipende. Di solito la soluzione ideale è terminare qualunque cosa il thread stia facendo con garbo (es. Rollback di questa transazione, interruzione di un loop ecc.), Ma dipende molto dal contesto.
Konrad Garus,

quindi di cosa serve un timer? potresti ottenere la stessa funzionalità con un timer? Ho letto il documento java e menzionava qualcosa sui ritardi, ma essendo un principiante con il codice, sto per finire il mio secondo anno di programmazione al liceo, non sono del tutto sicuro se il ritardo di cui parla sarebbe utile qui, o anche il classe giusta da usare
Ungeheuer

195

Come altri utenti hanno detto, è necessario circondare la chiamata con un try{...} catch{...}blocco. Ma da quando è stato rilasciato Java 1.5, esiste la classe TimeUnit che fa lo stesso di Thread.sleep (millis) ma è più conveniente. È possibile selezionare l'unità di tempo per l'operazione di sospensione.

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
}

Inoltre ha metodi aggiuntivi: Documentazione Oracle TimeUnit


6
Vedere altre risposte per esempio su come circondare queste chiamate con la try-catchgestione delle eccezioni richiesta .
Basil Bourque,

2
Non dimenticare "import java.util.concurrent.TimeUnit;"
coder


13

Utilizzare il seguente costrutto di codifica per gestire le eccezioni

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

8

Metti il ​​tuo Thread.sleepin un blocco catch tentativo

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

7

Quando utilizzo Android (l'unica volta che utilizzo Java), consiglierei di utilizzare un gestore invece di mettere il thread in modalità di sospensione.

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

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


4
Questo è per Android non per Core Java
Ganesh Krishnan il

3

Prova questo:

try{

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

8
Non è una cattiva pratica catturare Exceptionin Java?
Michael Dorst,

2
Meglio catturare InterruptedException come le altre risposte qui
devsaw

6
Questo si chiama "Pokemon Exception Handler" - devo prenderli tutti.
James Tayler

3

I miei modi per aggiungere ritardo a un programma 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   
    }
}

Questo è per il ritardo sequenziale ma per i ritardi del loop fare riferimento a Ritardo / Attesa Java .


Si noti che la palese autopromozione non è consentita qui. Vedi l'ultimo punto qui nel Centro assistenza . Tuttavia, puoi inserire il link nel tuo profilo, ciò è consentito.
SL Barth - Ripristina Monica il

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
}

per esempio:-

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

Un modo più semplice di aspettare è usare System.currentTimeMillis(), che restituisce il numero di millisecondi dalla mezzanotte del 1 gennaio 1970 UTC. Ad esempio, per attendere 5 secondi:

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

In questo modo, non devi preoccuparti di discussioni ed eccezioni. Spero che questo ti aiuti!


Questo consuma CPU durante l'attesa.
yacc,

@yacc Questo è vero, ma è più semplice dell'uso dei thread e non usa troppa CPU.
Sam,

0

Utilizzare java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Dormire per un secondo o

TimeUnit.MINUTES.sleep(1);

Dormi un minuto.

Poiché si tratta di un ciclo, ciò presenta un problema intrinseco: la deriva. Ogni volta che esegui il codice e poi dormi, ti allontanerai un po 'dall'esecuzione, diciamo, ogni secondo. Se questo è un problema, non utilizzare sleep.

Inoltre, sleepnon è molto flessibile quando si tratta di controllo.

Per eseguire un'attività ogni secondo o con un ritardo di un secondo, consiglio vivamente un [ ScheduledExecutorService] [1] e [ scheduleAtFixedRate] [2] o [ scheduleWithFixedDelay] [3].

Per eseguire il metodo myTaskogni secondo (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() è semplice per i principianti e può essere appropriato per test unitari e prove concettuali.

Ma NON utilizzare sleep()per il codice di produzione. Alla fine sleep()potrebbe morderti male.

Best practice per le applicazioni java multithread / multicore per utilizzare il concetto di "thread wait". Wait rilascia tutti i blocchi e i monitor mantenuti dal thread, il che consente ad altri thread di acquisire quei monitor e procedere mentre il thread è in modalità di sospensione.

Il codice seguente dimostra questa tecnica:

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 implementazione:

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

In alternativa, se non si desidera gestire i thread, provare questo metodo:

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

Inizia quando lo chiami e termina quando è trascorso il numero di secondi.


7
Ciò consumerebbe CPU durante il tempo di sospensione. Su Thread.sleep () il thread può essere programmato.
Vivek Pandey,

sei ridi e non c'è acqua: D
M410

17
user2276378 aveva frainteso l'inglese della domanda. OP ha dichiarato di non essere "in grado di utilizzare il sonno o l'attesa", che user2276378 pensava che non potesse usarli (o che non gli fosse permesso di usarli) e quindi ha fornito una soluzione valida che non ha utilizzato il sonno o l'attesa. Cerca di non essere un inglese troppo duro non è la prima lingua di tutti.
David Newcomb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.