Я получаю исключение при использовании Thread.sleep (x) или wait ()


343

Я пытался отложить (или уложить в сон) мою Java-программу, но произошла ошибка.

Я не могу использовать Thread.sleep(x)или wait(). Появляется то же сообщение об ошибке:

незарегистрированное исключение java.lang.InterruptedException; должен быть пойман или объявлен брошенным.

Требуется ли какой-либо шаг перед использованием методов Thread.sleep()или wait()?


8
Ну, это популярно. Должно быть огромное количество людей, которым нужно отложить свою Java-программу на несколько секунд. Трудно представить. Конечно, правильное название на посту очень помогло бы.
Роберт Харви

Ответы:


575

У вас впереди много чтения. От ошибок компилятора до обработки исключений, потоков и прерываний потоков. Но это будет делать то, что вы хотите:

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

1
спасибо за вашу помощь, я смог запустить его .. кроме того, что использовать для catch (interruptedException ex)
Винсент

4
Смотрите ответ от Авеля. Google для InterruptedException. Короче говоря: поток может быть прерван во время сна, и это своего рода исключение, которое необходимо явно обработать.
Конрад Гарус

8
Некоторые ответы говорят, что ничего не делать с исключением, некоторые говорят, что нужно выбросить, это говорит interrupt (). Кто-нибудь захочет обсудить, что подходит и почему?
Сума

6
@Suma Есть много дискуссий по этому вопросу, в том числе и переполнение стека. Просто ищите это. Слишком долго для комментария. Через несколько лет единственный ответ, который у меня есть: это зависит. Обычно идеальным решением является завершение того, что поток делает изящно (например, откат этой транзакции, разрыв цикла и т. Д.), Но это очень зависит от контекста.
Конрад Гарус

так для чего нужен таймер? Вы могли бы достичь той же функциональности с помощью таймера? Я читал документацию по Java, и там упоминалось кое-что о задержках, но, будучи новичком в коде, я собираюсь закончить второй год обучения в средней школе, я не совсем уверен, будет ли здесь полезна задержка, о которой идет речь, или даже правильный класс для использования
Ungeheuer

195

Как говорили другие пользователи, вы должны окружить свой вызов try{...} catch{...}блоком. Но так как Java 1.5 была выпущена, есть класс TimeUnit, который делает то же самое, что Thread.sleep (миллис), но более удобный. Вы можете выбрать единицу времени для режима сна.

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
}

Также у него есть дополнительные методы: TimeUnit Oracle Documentation


6
Посмотрите другие ответы, например, как окружить эти вызовы необходимой try-catchобработкой исключений.
Базилик Бурк

2
Не забудьте "импортировать java.util.concurrent.TimeUnit;"
кодер


13

Используйте следующую конструкцию кодирования для обработки исключений

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

8

Поместите свой Thread.sleepблок в попытку поймать

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

7

При использовании Android (единственный раз, когда я использую Java), я бы рекомендовал использовать обработчик вместо того, чтобы перевести поток в спящий режим.

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

Ссылка: http://developer.android.com/reference/android/os/Handler.html


4
Это для Android, а не для Core Java
Ганеш Кришнан

3

Попробуй это:

try{

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

8
Разве это не плохая практика ловить Exceptionна Java?
Майкл Дорст

2
Лучше поймать InterruptedException, как и другие ответы здесь
devsaw

6
Это называется «Pokemon Exception Handler» - должен поймать их всех.
Джеймс Тейлер

3

Мои способы добавить задержку в программу 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   
    }
}

Это для последовательной задержки, но для петлевых задержек обратитесь к Java Delay / Wait .


Обратите внимание, что явная самореклама здесь запрещена. Смотрите последний пункт здесь, в справочном центре . Однако вы можете разместить ссылку в своем профиле - это разрешено.
SL Barth - Восстановить Монику

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
}

например:-

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

Более простым способом ожидания является использование System.currentTimeMillis(), которое возвращает количество миллисекунд с полуночи 1 января 1970 года по Гринвичу. Например, подождать 5 секунд:

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

Таким образом, вам не нужно копаться с потоками и исключениями. Надеюсь это поможет!


Это потребляет процессор во время ожидания.
YACC

@yacc Это правда, но это проще, чем использование потоков и не требует слишком много ресурсов процессора.
Сэм

0

Используйте java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Спи одну секунду или

TimeUnit.MINUTES.sleep(1);

Спи минуту.

Поскольку это цикл, это представляет собой внутреннюю проблему - дрейф. Каждый раз, когда вы запускаете код, а затем засыпаете, вы будете немного отвлекаться, скажем, каждую секунду. Если это проблема, не используйте sleep.

Кроме того, sleepне очень гибкий, когда дело доходит до контроля.

Для запуска задачи каждую секунду или с задержкой в ​​одну секунду я настоятельно рекомендую [ ScheduledExecutorService] [1] и либо [ scheduleAtFixedRate] [2] или [ scheduleWithFixedDelay] [3].

Чтобы запустить метод myTaskкаждую секунду (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() прост для начинающих и может подойти для модульных тестов и проверки концепции.

Но, пожалуйста, НЕ используйте sleep()для производственного кода. В конце концов sleep()может сильно укусить вас.

Для многопоточных / многоядерных Java-приложений рекомендуется использовать концепцию «ожидание потока». Wait освобождает все блокировки и мониторы, удерживаемые потоком, что позволяет другим потокам получать эти мониторы и продолжать работу, пока ваш поток мирно спит.

Код ниже демонстрирует эту технику:

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 реализация:

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

В качестве альтернативы, если вы не хотите иметь дело с потоками, попробуйте этот метод:

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

Он начинается, когда вы звоните, и заканчивается, когда прошло количество секунд.


7
Это будет потреблять процессор во время сна. На Thread.sleep () поток может быть отменен.
Вивек Пандей

ты ridi и нет воды: D
M410

17
Пользователь 2276378 неправильно понял вопрос по-английски. OP сказал, что он «не мог использовать сон или ожидание», что, по мнению пользователя 2276378, означало, что он не мог их использовать (или ему не разрешалось их использовать), и поэтому он предоставил правильное решение, которое не использовало сон или ожидание. Старайтесь не быть слишком резким, английский не является родным языком.
Дэвид Ньюкомб
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.