在Java的线程里面有几个比较常见的方法如sleep,wait,yield,但是你知道它们之间的区别吗?
首先这三种方法都可以用来暂停线程,sleep和yield方法都定义在Thread类中,而wait方法则定义在Object类中,wait和sleep的关键区别在于前者是用来做线程间通信交流用的,而后者是为了让当前线程在一定的周期内休眠,此外调用wait方法会释放当前线程的锁,而sleep方法则绝不会释放任何监视器。接下来我们再来看下yield方法,它和wait,sleep方法有一些轻微的不同,它仅仅释放当前线程的cpu,让别的线程有机会去运行,当然这里的有机会是有条件的,只有优先级等于或者大于该线程的线程才有可能得到,如果小于该线程优先级的线程是不会得到的,所以其不保证谁会得到cpu资源,它完全依赖线程调度,很大程度上还是该线程会再次获得cpu资源,所以可以理解它是不可靠的,仅仅是提供了一种可能。
关于sleep和wait,yield,这里还得延伸一个概念,那就是关于线程上下文切换,如果当多个线程共享一个cpu的时候,他们其实是通过上下文切换来让每个应用程序都能够获取到一些cpu时间片来执行任务。这里有一个非常基础的概念,一个进程可以通过上下文切换来让另一个进程也有机会运行,即使在单核的系统中,类似于进程切换,多个线程也可以在Jvm进程中自由切换。
提到这里,我们有必要来重新复习一下线程的六种状态:
(1)NEW 是指创建了线程类,但是还没有执行start方法时候的线程状态
(2)RUNNABLE 是指线程在JVM中正在运行,当然这里并不一定就是在操作系统中正在进行,比如说其正在等待分配cpu时间片
(3)WAITING是指当先线程已经进入同步块,但是如果其调用了wait方法,那么它将会无限等待直到有一些线程在同样的监视器条件下调用了notify方法来唤醒它。
(4)BLOCKED 是指当线线程正在等待获取一个监视器,这里需要注意的是在一个WAITING状态的线程如果被调用了notify方法,那么其不会立即切换到RUNNABLE状态,而是会先切成BLOCKED状态等待获取一个监视器锁,如果其他的一些线程得到了锁,那么其将还会切回到WAITING状态
(5)TIMED_WAITING是指当线线程调用了sleep方法或者时调用了wait(timeout)超时的方法。
(6)TERMINATED是指当前线程已经结束。
当线程sleep调用时,会发生什么?
(1)当前线程会被转换为TIMED_WAITING状态在一定间隔周期内
(2)释放当前的cpu资源
(3)当等待的时间过期后,线程不会立刻切换到该线程,如果还有更高优先级的任务在运行。
(4)线程sleep可以被线程的interrupted打断,如果被打断会抛出InterruptedException
当wait方法调用时,会发生什么。
(1)释放当前的cpu资源,进入WAITING状态
(2)释放监视器对象,任何其他的线程可以进入这个同步块
(3)如果同一个监视器下面有线程调用了notify,该线程不会立刻进入运行状态而是为再次请求获得锁,如果没有获得还会回到WAITING状态。
总结:
本文主要介绍了在Java线程里面sleep,wait,yield的区别和联系,他们都有暂停当前线程的功能,但是彼此又有不同的特点,此外线程的状态的改变是需要上下文切换来取得,如果上下文频繁切换的时间大于线程暂停的时间,那么对于程序性能来说是一种损失,在大多使用while循环里面的sleep时,好的习惯是使用wait来代替每次固定间隔的判断,这样会更高效的利用cpu。至于线程的yield,因为具有不确定性,所以使用它并不保证其他的线程就一定能够获得资源来执行任务。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有