从Java线程到kotlin协程之线程休眠 (sleep)

Posted XeonYu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Java线程到kotlin协程之线程休眠 (sleep)相关的知识,希望对你有一定的参考价值。

上一篇:从Java线程到kotlin协程之线程的状态

上一篇在看线程状态的时候我们用到了线程的几个方法例如:
sleep join 实际上,这些方法就是对线程的调度(scheduled)

本篇文章,我们先来看看线程的sleep


sleep 线程休眠

sleep是让当前线程进入休眠状态,让出CPU资源,但是不会释放锁。
使用场景:延时执行
例如,android中的版本更新逻辑,一般我们是在进入主页面几秒后去请求接口获取版本更新信息,就可以用sleep实现。

我们先来看下源码:

在这里插入图片描述

可以看到,sleep() 方法是一个静态的本地方法,接收一个long类型的毫秒值。

我们先来用一下:

    public static void main(String[] args) {

        Thread thread = new Thread(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + "线程开始执行");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadName + "任务执行完毕");
        }, "work");

        thread.start();

        System.out.println("main线程执行");
        
    }

运行结果:

在这里插入图片描述
可以看到,work线程休眠了两秒

这里有一个小坑,需要注意下:
我们看到了源码是一个static修饰的方法,那也就是说我们也可以通过对象去调用,下面我们通过对象调用看看是什么效果。

    public static void main(String[] args) {

        Thread thread = new Thread(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + "线程开始执行");
            System.out.println(threadName + "任务执行完毕");
        }, "work");


        thread.start();
        try {
            thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("main线程执行");

    }

运行结果如下,可以看到,虽然我们调用的是thread.sleep(),但实际休眠的是主线程。
在这里插入图片描述

也就是说,sleep方法的调用只跟当前线程有关,在哪个线程调sleep,哪个线程就会休眠。

下面我们多加点打印看下是不是这样:

    public static void main(String[] args) {

        Thread thread = new Thread(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + "线程开始执行");
            try {
                System.out.println(threadName + "开始休眠");
                Thread.sleep(3000);
                System.out.println(threadName + "休眠完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadName + "任务执行完毕");
        }, "work");


        thread.start();

        String threadName = Thread.currentThread().getName();
        try {
            System.out.println(threadName + "开始休眠");
            thread.sleep(2000);
            System.out.println(threadName + "休眠完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(threadName + "线程执行完毕");

    }

运行结果如下:

在这里插入图片描述

可以看到,确实是 在哪个线程调sleep,哪个线程就会休眠


使用TimeUnit来更简单的实现线程sleep

由于Thread的sleep方法接收的是一个long类型的毫秒值,也就是说,休眠的时间需要我们自己去换算,用起来不是很方便。我们可以用 package java.util.concurrent 包下面的 TimeUnit 来更简单的实现线程的sleep。

先看下TimeUnit源码中的属性和方法,如下:
在这里插入图片描述
可以看到,TimeUnit给我们提供好了时间的单位,以及相互转换的方法,还提供了sleep方法。
在这里插入图片描述

可以看到,最终调用的还是Thread的sleep方法,帮我们实现了转换时间的代码。

我们来用一下:

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + "线程开始执行");
            try {
                System.out.println(threadName + "开始休眠");
                TimeUnit.MILLISECONDS.sleep(2000);//休眠2000毫秒
                System.out.println(threadName + "休眠完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadName + "任务执行完毕");
        }, "work");
        thread.start();
        String threadName = Thread.currentThread().getName();
        try {
            System.out.println(threadName + "开始休眠");
            TimeUnit.SECONDS.sleep(1);//休眠1秒
            System.out.println(threadName + "休眠完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(threadName + "线程执行完毕");
    }

运行结果如下:
在这里插入图片描述

好了,线程的休眠就是这些


如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

以上是关于从Java线程到kotlin协程之线程休眠 (sleep)的主要内容,如果未能解决你的问题,请参考以下文章

从Java线程到kotlin协程之线程合并 (join)

从Java线程到kotlin协程之线程的状态

从Java线程到kotlin协程之线程同步(synchronized关键字)

从Java线程到kotlin协程之线程的基本使用

从Java线程到kotlin协程之多线程的基本概念

Kotlin SharedFlow&StateFlow 热流到底有多热?