【问题标题】:I get exception when using Thread.sleep(x) or wait()使用 Thread.sleep(x) 或 wait() 时出现异常
【发布时间】:2011-03-21 12:52:08
【问题描述】:

我试图延迟或进入睡眠状态我的 Java 程序,但出现错误。

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

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

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

【问题讨论】:

  • 嗯,这很受欢迎。一定有大量的人需要延迟他们的 Java 程序几秒钟。很难想象。当然,在帖子上加上正确的标题会大有帮助。

标签: java sleep


【解决方案1】:

你有很多阅读要做。从编译器错误到异常处理、线程和线程中断。但这会做你想做的事:

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

【讨论】:

  • 感谢您的帮助,我可以运行它了.. 另外,catch(interruptedException ex) 有什么用
  • 查看 Abel 的回复。谷歌查询中断异常。长话短说:线程可以在睡眠时被中断,这是一种需要明确处理的异常。
  • 一些答案​​告诉对异常不做任何事情,有人说抛出,这告诉中断()。有人愿意讨论哪个合适吗?为什么?
  • @Suma 有很多关于它的讨论,包括 Stack Overflow 本身。只是搜索它。评论太长了。几年后,我唯一的答案是:视情况而定。通常理想的解决方案是终止线程正常执行的任何操作(例如回滚此事务、中断循环等),但这非常依赖于上下文。
  • 那么计时器的用途是什么?你能用定时器实现同样的功能吗?我阅读了 java 文档,它提到了一些关于延迟的内容,但是作为一个有代码的新手,我即将完成我的高中编程的第二年,我不完全确定它所谈论的延迟是否在这里有用,甚至使用正确的类
【解决方案2】:

看看at this excellent brief post 如何正确执行此操作。

基本上:抓住InterruptedException。请记住,您必须添加此捕获块。这篇文章进一步解释了这一点。

【讨论】:

    【解决方案3】:

    使用以下编码结构来处理异常

    try {
      Thread.sleep(1000);
    } catch (InterruptedException ie) {
        //Handle exception
    }
    

    【讨论】:

      【解决方案4】:

      将您的 Thread.sleep 放入 try catch 块中

      try {
          //thread to sleep for the specified number of milliseconds
          Thread.sleep(100);
      } catch ( java.lang.InterruptedException ie) {
          System.out.println(ie);
      }
      

      【讨论】:

        【解决方案5】:

        试试这个:

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

        【讨论】:

        • 在 Java 中捕获 Exception 不是不好的做法吗?
        • 像这里的其他答案一样更好地捕捉 InterruptedException
        • 这被称为“口袋妖怪异常处理程序” - 必须全部捕获。
        【解决方案6】:

        或者,如果您不想处理线程,请尝试以下方法:

        public static void pause(int seconds){
            Date start = new Date();
            Date end = new Date();
            while(end.getTime() - start.getTime() < seconds * 1000){
                end = new Date();
            }
        }
        

        它在您调用它时开始,并在经过秒数时结束。

        【讨论】:

        • 这会在睡眠期间消耗 CPU。在 Thread.sleep() 上,线程可以被取消调度。
        • 你是ridi,没有水:D
        • user2276378 误解了问题的英语。 OP 说他“无法使用睡眠或等待”,user2276378 认为这意味着他无法使用它们(或不允许使用它们),因此他提供了一个 valid 解决方案,该解决方案没有使用睡眠或等待。尽量不要太苛刻 英语不是每个人的第一语言。
        【解决方案7】:

        正如其他用户所说,您应该用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

        【讨论】:

        • 查看其他答案,例如如何使用所需的try-catch 异常处理来包围这些调用。
        • 别忘了“import java.util.concurrent.TimeUnit;”
        【解决方案8】:
        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);
        
        
          }
        }
        

        【讨论】:

          【解决方案9】:

          我为 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

          【讨论】:

          【解决方案10】:

          使用 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

          【讨论】:

          • 这是为 Android 而不是 Core Java
          【解决方案11】:

          更简单的等待方法是使用 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 确实如此,但比使用线程更简单,也不会占用太多CPU。
          【解决方案12】:

          使用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");
          }
          

          【讨论】:

            【解决方案13】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-11-27
              • 1970-01-01
              • 2011-10-15
              • 2015-02-05
              • 2014-08-06
              • 1970-01-01
              • 2011-09-15
              • 2016-11-08
              相关资源
              最近更新 更多