Как заставить поток спать в течение определенного времени в Java? - PullRequest
12 голосов
/ 26 сентября 2010

У меня есть сценарий, в котором я хочу, чтобы поток спал в течение определенного времени.

Код:

    public void run(){
        try{
            //do something
                     Thread.sleep(3000);
//do something after waking up
                }catch(InterruptedException e){
                // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
                }
        }

Теперь, как мне справиться со случаем, когда я пытаюсь запустить поток?бежать сбито с прерванным исключением до полного сна?Кроме того, поток просыпается после прерывания и переходит ли он в работоспособное состояние или когда только после того, как он переходит в работоспособное состояние, поток переходит к блоку перехвата?

Ответы [ 5 ]

10 голосов
/ 26 сентября 2010

Когда ваш поток подвергается прерыванию, он попадает в блок захвата InterruptedException.Затем вы можете проверить, сколько времени потратила нить на сон, и определить, сколько еще времени уходит на сон.Наконец, вместо того, чтобы проглотить исключение, рекомендуется восстановить состояние прерывания, чтобы код, находящийся выше стека вызовов, мог с ним справиться.

public void run(){

    //do something

    //sleep for 3000ms (approx)     
    long timeToSleep = 3000;
    long start, end, slept;
    boolean interrupted;

    while(timeToSleep > 0){
        start=System.currentTimeMillis();
        try{
            Thread.sleep(timeToSleep);
            break;
        }
        catch(InterruptedException e){

            //work out how much more time to sleep for
            end=System.currentTimeMillis();
            slept=end-start;
            timeToSleep-=slept;
            interrupted=true
        }
    }

    if(interrupted){
        //restore interruption before exit
        Thread.currentThread().interrupt();
    }
}
1 голос
/ 17 мая 2013

Я использую это так:

Так что нет необходимости ждать определенного времени до конца.

1 голос
/ 26 сентября 2010

Согласно этой странице вам придется ее кодировать, чтобы вести себя так, как вы хотите. Использование нити над вашим сном будет прервано и ваша нить выйдет. В идеале вы должны повторно генерировать исключение, чтобы независимо от того, какой поток был запущен, он мог предпринять соответствующие действия.

Если вы не хотите, чтобы это произошло, вы можете поместить все это в некоторое время (true) цикл. Теперь, когда происходит прерывание, сон прерывается, вы едите исключение и зацикливаетесь, чтобы начать новый сон.

Если вы хотите завершить 3 секунды сна, вы можете приблизить его, скажем, 10 снов по 300 миллисекунд и оставить счетчик цикла вне цикла while. Когда вы видите прерывание, съешьте его, установите флаг «Я должен умереть» и продолжайте петлю, пока вы не выспитесь. Затем вы прерываете поток контролируемым образом.

Вот один из способов:

public class ThreadThing implements Runnable {
    public void run() {
        boolean sawException = false;
        for (int i = 0; i < 10; i++) {
            try {
                //do something
                Thread.sleep(300);
                //do something after waking up
            } catch (InterruptedException e) {
                // We lose some up to 300 ms of sleep each time this
                // happens...  This can be tuned by making more iterations
                // of lesser duration.  Or adding 150 ms back to a 'sleep
                // pool' etc.  There are many ways to approximate 3 seconds.
                sawException = true;
            }
        }
        if (sawException) Thread.currentThread().interrupt();
    }
}
1 голос
/ 26 сентября 2010

Почему вы хотите спать ровно 3 секунды?Если через какое-то время нужно просто что-то выполнить, попробуйте использовать Timer .

1 голос
/ 26 сентября 2010
  1. Использование Sleep в моем опыте обычно для компенсации неудачного выбора времени где-нибудь в программе, пересмотрите!
  2. попробуйте это:

    public void run(){
            try{
                //do something
                long before = System.currentTimeMillis();
                Thread.sleep(3000);
                //do something after waking up
            }catch(InterruptedException e){
                long diff = System.currentTimeMillis()-before;
                //this is approximation! exception handlers take time too....
                if(diff < 3000)
                    //do something else, maybe go back to sleep.
                    // interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
            }
    }
    
  3. если вы не прерываете сон самостоятельно, с какой стати эта нить проснется?кажется, что вы делаете что-то очень неправильно ...

...