SystemClock.sleep()方法与Thread.sleep()方法的区别

直接上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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值