直接上SystemClock.sleep()的源代码:
public static void sleep(long ms)
{
/**
* uptimeMillis():是指开机到当前时间的时长,区别于System.currentTimeMillis()获取的是系统的时间
* 具体区别在下面会解释
*/
//获取当前时长 A
long start = uptimeMillis();
//休眠的时长
long duration = ms;
//是否终端当前线程的标志
boolean interrupted = false;
// 确保线程睡眠时长为ms
do {
try {
Thread.sleep(duration);
}
catch (InterruptedException e) {
interrupted = true;
}
// 这个算式得到的 duration 为 线程睡眠的剩余时间,反复执行Thread.sleep()
duration = start + ms - uptimeMillis();
} while (duration > 0);
if (interrupted) {
//Important: we don't want to quietly eat an interrupt() event,
//so we make sure to re-interrupt the thread so that the next
//call to Thread.sleep() or Object.wait() will be interrupted.
//调用线程的interrupt方法,并不能真正中断线程,只是给线程的中断状态的标志设置为 true
Thread.currentThread().interrupt();
}
Waits a given number of milliseconds (of uptimeMillis) before returning. Similar to sleep(long), but does not throw InterruptedException; interrupt() events are deferred until the next interruptible operation. Does not return until at least the specified number of milliseconds has elapsed.
翻译(水平有限,请见谅):
返回之前等待设置的时长,类似于 Thread.sleep(long ms),但是不抛出 InterruptedException , interrupt() 事件被延时到下次中断操作上,直到经过声明的时长后才返回。
常见的 InterruptedException 处理方式:
把异常捕捉但是不做其他处理,这种做法埋下了一个隐患–可能会导致中断的发生。而中断可能导致应用程序丧失及时取消活动或关闭的能力。因为线程在检查中断标示时如果发现中断标示为true,则会在常见阻塞方法(sleep、join、wait、1.5中的condition.await及可中断的通道上的 I/O 操作方法)调用处抛出InterruptedException异常,在抛出异常后立即将线程的中断标示位清除,即重新设置为false。抛出 InterruptedException异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求,同时在结束线程前让程序员来处理中断请求(下面会结合 Thread 的源码来分析)。
所以这句代码:Thread.currentThread().interrupt();
相当于将线程手动唤醒。
下面来看一下Thread.sleep()的源码:
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds plus the specified
* number of nanoseconds, subject to the precision and accuracy of system
* timers and schedulers. The thread does not lose ownership of any
* monitors.
*
* @param millis
* the length of time to sleep in milliseconds
*
* @param nanos
* {@code 0-999999} additional nanoseconds to sleep
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative, or the value of
* {@code nanos} is not in the range {@code 0-999999}
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("millis < 0: " + millis);
}
if (nanos < 0) {
throw new IllegalArgumentException("nanos < 0: " + nanos);
}
if (nanos > 999999) {
throw new IllegalArgumentException("nanos > 999999: " + nanos);
}
// The JLS 3rd edition, section 17.9 says: "...sleep for zero
// time...need not have observable effects."
if (millis == 0 && nanos == 0) {
// ...but we still have to handle being interrupted.
if (Thread.interrupted()) {
throw new InterruptedException();
}
return;
}
long start = System.nanoTime();
long duration = (millis * NANOS_PER_MILLI) + nanos;
Object lock = currentThread().lock;
// Wait may return early, so loop until sleep duration passes.
synchronized (lock) {
while (true) {
sleep(lock, millis, nanos);
long now = System.nanoTime();
long elapsed = now - start;
if (elapsed >= duration) {
break;
}
duration -= elapsed;
start = now;
millis = duration / NANOS_PER_MILLI;
nanos = (int) (duration % NANOS_PER_MILLI);
}
}
}
上述代码利用 System.nanoTime() 函数来确保时间的精准。请注意
if any thread has interrupted the current thread. The interrupted status of the current thread is
cleared when this exception is thrown.
如果其它任意进程中断了这个进程发出两个动作(和上面的结论一致):
1.抛出 InterruptedException 。
2. 当前线程 interrupted status 被清除。
对于 java 的线程中断请参看这篇文章:
https://www.cnblogs.com/onlywujun/p/3565082.html