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

2023-01-18 10:42:01 买帖  | 投诉/举报

篇首语:本文由小编为大家整理,主要介绍了从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)的主要内容,如果未能解决你的问题,请参考以下文章