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

2022-09-04 03:16:53

我有一个场景,我希望线程休眠特定的时间量。

法典:

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

现在,我如何处理我试图运行的线程在睡眠完成之前被中断的异常击中的情况?另外,线程在被中断后是否会唤醒,它是否进入可运行状态,或者什么时候只有在它进入可运行之后,流才会进入捕获块?


答案 1

当您的线程被中断击中时,它将进入捕获块。然后,您可以检查线程花了多少时间睡觉,并计算出还有多少时间可以睡觉。最后,最好不要吞下异常,而是恢复中断状态,以便调用堆栈上方的代码可以处理它。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();
    }
}

答案 2

根据此页面,您必须对其进行编码才能按照所需的方式运行。使用高于睡眠状态的线程将被中断,并且线程将退出。理想情况下,您将重新引发异常,以便线程启动的任何内容都可以采取适当的操作。

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

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

这是一种方法:

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