如何在java中让线程休眠特定的时间?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3797941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 05:08:12  来源:igfitidea点击:

How to make a thread sleep for specific amount of time in java?

javamultithreadingsleep

提问by arunc

I have a scenario where i want a thread to sleep for specific amount of time.

我有一个场景,我想让一个线程休眠特定的时间。

Code:

代码:

    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?
                }
        }

Now how do i handle the case where the thread i am trying to run is hit with an interrupted exception before the complete of the sleep? Also does the thread wake up after being interrupted and does it go to runnable state or when is it that only after it goes to runnable does the flow go to catch block?

现在我如何处理我试图运行的线程在睡眠完成之前遇到中断异常的情况?线程是否在被中断后唤醒并进入可运行状态,或者只有在进入可运行状态后,流程才会进入 catch 块?

回答by codeScriber

  1. using Sleep in my experience is usually to compensate for bad timing somewhere else in the program, reconsider!
  2. try this:

    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. if you do not interrupt the sleep yourself, why would this thread be awoken ? is seems that you are doing something very wrong...

  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. 如果你不自己中断睡眠,为什么这个线程会被唤醒?似乎你做错了什么......

回答by Tony Ennis

According to this pageyou'll have to code it to behave the way you want. Using the thread above your sleep will be interrupted and your thread will exit. Ideally, you'd re-throw the exception so that whatever started the thread could take appropriate action.

根据此页面,您必须对其进行编码以使其按照您想要的方式运行。使用睡眠上方的线程将被中断,您的线程将退出。理想情况下,您会重新抛出异常,以便线程启动的任何内容都可以采取适当的操作。

If you don't want this to happen, you could put the whole thing in a while(true) loop. Now when the interrupt happens the sleep is interrupted, you eat the exception, and loop up to start a new sleep.

如果你不希望这种情况发生,你可以把整个事情放在一个 while(true) 循环中。现在当中断发生时睡眠被中断,你吃掉异常,然后循环开始一个新的睡眠。

If you want to complete the 3 seconds of sleep, you can approximate it by having, say, 10 sleeps of 300 milliseconds, and keeping the loop counter outside a while loop. When you see the interrupt, eat it, set a "I must die" flag, and continue looping until you have slept enough. Then you interrupt the thread in a controlled manner.

如果你想完成 3 秒的睡眠,你可以通过让 10 次睡眠 300 毫秒来近似它,并将循环计数器保持在 while 循环之外。当你看到中断时,吃掉它,设置一个“我必须死”的标志,然后继续循环直到你睡够了。然后以受控方式中断线程。

Here's one way:

这是一种方法:

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

回答by Jorn

Why do you want to sleep for exactly 3 seconds? If it's just having to execute something after some time, try using a Timer.

为什么要睡正好 3 秒?如果它只是在一段时间后执行某些操作,请尝试使用Timer

回答by dogbane

When your thread is hit by an interrupt it will go into the InterruptedExceptioncatch block. You can then check how much time the thread has spent sleeping and work out how much more time there is to sleep. Finally, instead of swallowing the exception, it is good practice to restore the interruption status so that code higher up the call stack can deal with it.

当您的线程被中断击中时,它将进入InterruptedExceptioncatch 块。然后,您可以检查线程花费了多少时间休眠并计算出还有多少时间可以休眠。最后,与其吞下异常,不如恢复中断状态,以便调用堆栈上层的代码可以处理它。

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

回答by scx

I use it this way:

我这样使用它:

So it is not necessary to wait the specific time to end.

所以没有必要等待特定时间结束。

public void run(){

    try {

        //do something

        try{Thread.sleep(3000);}catch(Exception e){}

        //do something

    }catch(Exception e){}

}