Recebo exceção ao usar Thread.sleep (x) ou wait ()

343

Tentei atrasar - ou adormecer - meu programa Java, mas ocorreu um erro.

Não consigo usar Thread.sleep(x)ou wait(). A mesma mensagem de erro aparece:

exceção não relatada java.lang.InterruptedException; deve ser capturado ou declarado lançado.

É necessário executar alguma etapa antes de usar os métodos Thread.sleep()ou wait()?

vincent low
fonte
8
Bem, isso é popular. Deve haver um número enorme de pessoas que precisam atrasar seu programa Java por alguns segundos. Difícil de imaginar. É claro que colocar o título correto na postagem ajudaria imensamente.
Robert Harvey

Respostas:

575

Você tem muita leitura pela frente. Desde erros do compilador até manipulação de exceções, encadeamento e interrupções de encadeamento. Mas isso fará o que você deseja:

try {
    Thread.sleep(1000);                 //1000 milliseconds is one second.
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}
Konrad Garus
fonte
11
obrigado pela sua ajuda, eu sou capaz de executá-lo .. ao lado, qual é o uso de catch (interruptedException ex)
vincent low
4
Veja a resposta de Abel. Google para InterruptedException. Resumindo uma longa história: o encadeamento pode ser interrompido durante o sono e esse é um tipo de exceção que precisa ser explicitamente tratado.
31510 Konrad Garus
8
Algumas respostas dizem para não fazer nada na exceção, outras dizem para jogar, isso diz para interromper (). Alguém gostaria de discutir o que é apropriado e por quê?
Suma
6
@ Suma Há muita discussão sobre isso, incluindo o próprio Stack Overflow. Basta procurar por isso. Muito tempo para um comentário. Depois de alguns anos, a única resposta que tenho é: depende. Geralmente, a solução ideal é finalizar o que o thread estiver fazendo normalmente (por exemplo, reverter essa transação, interromper um loop etc.), mas isso depende muito do contexto.
Konrad Garus
Então, para que serve um temporizador? você poderia obter a mesma funcionalidade com um timer? Eu li o java doc, e ele mencionou algo sobre atrasos, mas, sendo um novato com código, estou prestes a terminar meu segundo ano de programação do ensino médio. Não tenho certeza se o atraso que ele fala seria útil aqui, ou mesmo classe certa de usar
Ungeheuer
195

Como outros usuários disseram, você deve cercar sua chamada com um try{...} catch{...}bloco. Mas desde que o Java 1.5 foi lançado, há a classe TimeUnit que faz o mesmo que Thread.sleep (millis), mas é mais conveniente. Você pode escolher a unidade de tempo para operação em suspensão.

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
}

Também possui métodos adicionais: TimeUnit Oracle Documentation

Alexander Ivanov
fonte
6
Veja outras respostas, por exemplo, de como cercar essas chamadas com o try-catchtratamento de exceção necessário .
Basil Bourque
2
Não se esqueça de "importar java.util.concurrent.TimeUnit;"
coder
13

Use a seguinte construção de codificação para manipular exceções

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

Coloque o seu Thread.sleepem um bloco catch try

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

Ao usar o Android (o único momento em que uso Java), recomendo o uso de um manipulador, em vez de colocar o thread em suspensão.

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

Referência: http://developer.android.com/reference/android/os/Handler.html

Sindri Þór
fonte
4
Isto é para Android não para Núcleo Java
Ganesh Krishnan
3

Tente o seguinte:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}
SlickJava
fonte
8
Não é uma má prática capturar Exceptionem Java?
Michael Dorst
2
É melhor pegar o InterruptedException como as outras respostas aqui
devsaw 15/15
5
Isso é chamado de 'Pokemon Exception Handler' - precisa pegar todos.
James Tayler
3

Minhas maneiras de adicionar atraso a um programa 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   
    }
}

Isso é para atraso seqüencial, mas para atrasos de loop, consulte Java Delay / Wait .

DRBendanillo
fonte
Observe que a autopromoção flagrante não é permitida aqui. Veja o último ponto aqui na Central de Ajuda . No entanto, você pode colocar o link no seu perfil - isso é permitido.
SL Barth - Restabelece 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
}

por exemplo:-

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
fonte
0

Uma maneira mais simples de esperar é usar System.currentTimeMillis(), que retorna o número de milissegundos desde a meia-noite de 1 de janeiro de 1970 no UTC. Por exemplo, para aguardar 5 segundos:

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

Dessa forma, você não precisa se preocupar com threads e exceções. Espero que isto ajude!

Sam
fonte
Isso consome a CPU enquanto aguarda.
yacc
@ yacc Isso é verdade, mas é mais simples do que usar threads e não usa muita CPU.
Sam
0

Use java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Durma por um segundo ou

TimeUnit.MINUTES.sleep(1);

Durma por um minuto.

Como se trata de um loop, isso apresenta um problema inerente - desvio. Toda vez que você executa o código e, em seguida, dorme, estará um pouco à deriva, digamos, a cada segundo. Se este for um problema, não use sleep.

Além disso, sleepnão é muito flexível quando se trata de controle.

Para executar uma tarefa a cada segundo ou com um atraso de um segundo, recomendo fortemente um [ ScheduledExecutorService] [1] e [ scheduleAtFixedRate] [2] ou [ scheduleWithFixedDelay] [3].

Para executar o método a myTaskcada segundo (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
fonte
0

Thread.sleep() é simples para iniciantes e pode ser apropriado para testes de unidade e provas de conceito.

Mas por favor, NÃO use sleep()para código de produção. Eventualmentesleep() pode morder você muito.

Prática recomendada para aplicativos Java multithread / multicore para usar o conceito "thread wait". O Wait libera todos os bloqueios e monitores mantidos pelo encadeamento, o que permite que outros encadeamentos adquiram esses monitores e prossigam enquanto o encadeamento está dormindo pacificamente.

O código abaixo demonstra essa técnica:

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 implementação:

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
fonte
-2

Como alternativa, se você não quiser lidar com threads, tente este método:

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

Começa quando você liga e termina quando o número de segundos se passa.

user2276378
fonte
7
Isso consumiria a CPU durante o tempo de suspensão. Em Thread.sleep (), o thread pode ser desmarcado.
Vivek Pandey
você é ridi e não há água: D
M410 06/07
17
user2276378 havia entendido errado o inglês da pergunta. OP disse que estava "incapaz de dormir ou esperar", o que o usuário2276378 achou que ele não podia usá-los (ou não tinha permissão para usá-los) e, portanto, forneceu uma solução válida que não usava sono ou espera. Tente não ser muito severo O inglês não é a primeira língua de todos.
David Newcomb