使用Thread.sleep(x)或wait()时出现异常


343

我试图延迟-或使我的Java程序进入睡眠状态,但是发生错误。

我无法使用Thread.sleep(x)wait()。出现相同的错误消息:

未报告的异常java.lang.InterruptedException; 必须被抓住或宣布被抛出。

使用Thread.sleep()or wait()方法之前,是否需要任何步骤?


8
好吧,这很受欢迎。必须有很多人需要将Java程序延迟几秒钟。很难想象。当然,在帖子上贴上正确的标题将极大地帮助您。
罗伯特·哈维

Answers:


575

您前面有很多阅读材料。从编译器错误到异常处理,线程和线程中断。但这将满足您的要求:

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

1
感谢您的帮助,我能够运行它..旁边,有什么用渔获(InterruptedException的前)
文森特低

4
请参阅Abel的回复。Google for InterruptedException。简而言之:线程可以在睡眠时中断,这是一种异常,需要显式处理。
Konrad Garus

8
一些答案告诉对异常不做任何事情,有人说抛出,告诉中断()。有人会在乎讨论哪个合适以及为什么吗?
Suma

6
@Suma关于它的讨论很多,包括Stack Overflow本身。只是搜索它。评论太久了。几年后,我唯一的答案是:取决于情况。通常,理想的解决方案是终止线程正常运行的所有操作(例如,回滚该事务,中断循环等),但这取决于上下文。
Konrad Garus

因此,比计时器有什么用?您可以使用计时器实现相同的功能吗?我阅读了Java文档,其中提到了一些有关延迟的内容,但是作为一名具有代码的新手,我要完成第二年的高中编程工作,我不完全确定它所谈论的延迟在这里是否有用,甚至正确使用的类
Ungeheuer 2015年

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文档


6
例如,请参见其他答案,以了解如何用所需的try-catch异常处理来包围这些调用。
罗勒·布尔克

2
不要忘记“ import 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而不是针对Java核心的
Ganesh Krishnan

3

尝试这个:

try{

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

8
掌握ExceptionJava 并不是坏习惯吗?
2014年

2
像这里的其他答案一样,更好地捕获InterruptedException
devsaw

5
这就是所谓的“ Pokemon Exception Handler”(宠物小精灵异常处理程序),必须全部捕获。
James Tayler

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(),它返回自UTC 1970年1月1日午夜以来的毫秒数。例如,等待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
}

这样,您就不必为线程和异常而烦恼了。希望这可以帮助!


等待时会消耗CPU。
yacc

@yacc这是对的,但是它比使用线程更简单,并且不占用太多CPU。
山姆

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
这会在睡眠时间消耗CPU。在Thread.sleep()上可以调度线程。
Vivek Pandey

你是ridi,没有水:D
M410

17
user2276378误解了问题的英语。OP表示他“无法使用睡眠或等待”,user2276378认为这表示他无法使用(或不允许使用它们),因此他提供了不使用睡眠或等待的有效解决方案。尽量不要太苛刻英语不是每个人的母语。
David Newcomb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.