线程休眠 (sleep)
Posted XeonYu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程休眠 (sleep)相关的知识,希望对你有一定的参考价值。
上一篇:线程的状态
上一篇在看线程状态的时候我们用到了线程的几个方法例如:
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 + "线程执行完毕");
}
运行结果如下:
好了,线程的休眠就是这些
下一篇:
如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!
以上是关于线程休眠 (sleep)的主要内容,如果未能解决你的问题,请参考以下文章
C# 中的 Thread.Sleep():它是让实例化对象的线程休眠,还是让我从中调用方法的线程休眠?
Java多线程学习笔记— “Thread类三个方法:线程休眠sleep()线程礼让yield()线程强制执行join()”