关于java:使用Thread.sleep(x)或wait()时出现异常

I get exception when using Thread.sleep(x) or wait()

我试图延迟或睡觉-我的Java程序,但发生错误。

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

unreported exception java.lang.InterruptedException; must be caught or declared to be thrown.

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


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

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


正如其他用户所说,您应该用一个try{...} catch{...}块包围您的呼叫。但是由于Java 1.5被释放,TimeUnter类与线程睡眠(MILIS)相同,但更方便。您可以选择睡眠操作的时间单位。

1
2
3
4
5
6
7
8
9
10
11
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
}

此外,它还有其他方法:时间单位Oracle文档


请看一看这篇关于如何正确地完成这项工作的精彩的简短文章。

本质上:抓住InterruptedException。请记住,必须添加此catch块。这篇文章对此做了进一步的解释。


使用以下编码构造处理异常

1
2
3
4
5
try {
  Thread.sleep(1000);
} catch (InterruptedException ie) {
    //Handle exception
}

把你的Thread.sleep放在一个试捕区

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

当使用Android(我使用Java的唯一时间)时,我建议使用一个处理程序,而不是让线程睡觉。

1
2
3
4
5
6
7
8
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


我给Java程序增加延迟的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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延迟/等待。


1
2
3
4
5
6
7
8
9
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
}

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
"
+ a +"
"
+ b +"
"
+ 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);


  }
}

试试这个:

1
2
3
4
5
6
7
try{

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


Thread.sleep()对初学者来说很简单,可能适用于单元测试和概念验证。

但请不要使用sleep()作为生产代码。最终,sleep()可能会咬到你。

使用"线程等待"概念的多线程/多核Java应用程序的最佳实践。wait释放线程持有的所有锁和监视器,这允许其他线程获取这些监视器,并在您的线程平和睡眠时继续。

下面的代码演示了该技术:

1
2
3
4
5
6
7
8
9
10
11
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实施:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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();
        }
    }
}

使用java.util.concurrent.TimeUnit

1
TimeUnit.SECONDS.sleep(1);

睡眠一秒钟或

1
TimeUnit.MINUTES.sleep(1);

睡一分钟。

因为这是一个循环,所以这就提出了一个固有的问题——漂移。每次你运行代码然后睡觉的时候,你都会从运行中偏离一点,比如说,每秒钟。如果这是一个问题,那么不要使用sleep

而且,在控制方面,sleep并不是很灵活。

对于每秒钟或每延迟一秒运行一个任务,我强烈建议使用[ScheduledExecutorService][1]和[scheduleAtFixedRate][2]或[scheduleWithFixedDelay][3]。

运行方法EDCOX1,10秒每秒钟(Java 8):

1
2
3
4
5
6
7
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");
}


等待的一个简单方法是使用System.currentTimeMillis(),它返回自1970年1月1日UTC午夜以来的毫秒数。例如,要等待5秒:

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
    //some code
    long original = System.currentTimeMillis();
    while (true) {
        if (System.currentTimeMillis - original >= 5000) {
            break;
        }
    }
    //more code after waiting
}

这样,您就不必再为线程和异常操心了。希望这有帮助!


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

1
2
3
4
5
6
7
public static void pause(int seconds){
    Date start = new Date();
    Date end = new Date();
    while(end.getTime() - start.getTime() < seconds * 1000){
        end = new Date();
    }
}

它从您调用它时开始,到经过秒数时结束。