Я отримую виняток, коли використовую 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
дякую за вашу допомогу, я в змозі запустити його .. поряд, у чому полягає користь для вилову (перервано
Exxception

4
Дивіться відповідь Авеля. Google for InterruptedException. Короткий короткий опис: нитку можна перервати під час сну, і це свого роду виняток, з яким потрібно чітко поводитися.
Конрад Гарус

8
Деякі відповіді говорять нічого не робити за винятком, деякі кажуть кинути, це говорить переривати (). Хтось би дбав обговорити, що підходить і чому?
Сума

6
@Suma Є багато дискусій щодо цього, включаючи саму переповнення стека. Просто шукайте його. Занадто довго для коментаря. Через кілька років єдина відповідь, яку я маю, - це залежить. Зазвичай ідеальним рішенням є припинити все, що нитка робить витончено (наприклад, відкрутити цю транзакцію, розірвати цикл тощо), але це дуже залежить від контексту.
Конрад Гарус

тож ніж для чого таймер? ви могли б досягти тієї ж функціональності за допомогою таймера? Я читав java doc, і він згадував щось про затримки, але будучи новачком з кодом, я збираюся закінчити другий рік програмування в середній школі, я не зовсім впевнений, чи буде корисна затримка, про яку він говорить, або навіть правильний клас для використання
Ungeheuer

195

Як заявили інші користувачі, ви повинні оточити свій дзвінок try{...} catch{...}блоком. Але оскільки Java 1.5 була випущена, існує клас TimeUnit, який робить те саме, що і Thread.sleep (millis), але зручніше. Ви можете вибрати одиницю часу для режиму сну.

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
Ganesh Krishnan

3

Спробуйте це:

try{

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

8
Чи не погана практика ловити Exceptionна Java?
Майкл Дорст

2
Краще ловити InterruptedException, як інші відповіді тут
розроблено

6
Це називається "Покемон-обробник винятків" - треба спіймати їх усіх.
Джеймс Тейлер

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 року за UTC. Наприклад, почекати 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 для використання концепції "чекання потоку". Зачекайте, що вивільняються всі замки та монітори, що утримуються в потоці, що дозволяє іншим потокам придбати ці монітори та продовжувати, поки ваш потік спокійно спить.

Код нижче демонструє таку техніку:

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 () нитка може бути відкладена.
Вівек Пандей

ти риси і води немає: D
M410

17
user2276378 неправильно зрозумів питання англійською. ОП заявив, що "не в змозі використати сон або чекати", який вважав, що користувач2276378 означає, що він не може ними користуватися (або йому не дозволяється користуватися ними), і тому він надав дійсне рішення, яке не використовувало сон і не чекало. Постарайтеся не бути занадто суворими англійська мова не є першою мовою кожного.
Девід Ньюкомб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.