详细介绍一下Java中Thread.sleep和Thread.yield的区别和联系?

createh54个月前 (03-01)技术教程20

Thread.sleep和Thread.yield都是在Java中用来进行线程控制的操作方法,但是二者的使用场景和功能有所不同,下面我们就来详细介绍一下二者之间的区别和联系。

Thread.sleep

首先Thread.sleep方法是在Java的Thread类中支持的一个静态方法,其作用就是让线程暂停一段指定的时间,暂停的时间单位是毫秒。这个方法调用之后,会让线程进入到一个阻塞状态并且让出CPU的执行,允许其他线程使用CPU。它有两种使用方式。

  • Thread.sleep(long millis)
  • Thread.sleep(long millis, int nanos)

如下所示

public class SleepExample {
    public static void main(String[] args) {
        System.out.println("Thread is sleeping for 2 seconds...");
        try {
            Thread.sleep(2000); // 暂停2秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread woke up.");
    }
}

根据之前的介绍上面方法会让当前线程暂停2秒钟,时间结束之后,现成就会自动恢复到可运行的状态。有兴趣的读者可以将sleep方法和wait方法进行对比。Thread.sleep不会释放锁,当前线程在睡眠过程中持有的锁的状态不会发生变化,

当一个线程进入到Sleep之后,需要处理一个InterruptedException异常,因为在线程睡眠的过程中可能会被其他线程中断操作,这个时候就需要对InterruptedException异常进行处理。

Thread.yield

Thread.yield是Java中Thread类的另一个静态方法,这个方法的作用是主动的建议去让出当前线程对CPU的使用权,提供给其他优先级相同的线程或者是比它线程优先级更高的线程去获取CPU的使用权,但是这里需要注意这个方法只是建议线程让出CPU使用权,并不是一定会让出,也就是说JVM并不能保证线程会暂停,当然也不会保证其他线程一定会获取到使用CPU的机会。

其作用就是提示当前线程放弃CPU控制权,但是否真正让出是由JVM调度器决定。在一般情况下,如果有同优先级的线程在等待,当前线程将进入就绪状态,等待重新获得CPU资源。主要是用来调节线程的执行顺序,帮助避免某些线程长时间占用CPU,但通常很少在业务代码中直接使用。如下所示。

public class YieldExample {
    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " - Iteration: " + i);
                Thread.yield();
            }
        };

        Thread thread1 = new Thread(task, "Thread-1");
        Thread thread2 = new Thread(task, "Thread-2");
        
        thread1.start();
        thread2.start();
    }
}

这里需要注意,Thread.yield方法并不会抛出异常,当然也就不需要对任何的异常进行处理,当线程调用了yield方法之后,线程不会进入阻塞状态,而是进入就绪状态(Ready/Runnable),JVM可能会立刻重新调度当前线程继续执行,也可能让出CPU交给其他线程来使用。

区别和联系

比较维度

Thread.sleep

Thread.yield

作用

让当前线程暂停一段时间(毫秒/纳秒),进入阻塞状态。

让当前线程主动放弃 CPU 使用权,进入就绪状态。

是否保证让出 CPU

是,当前线程会进入阻塞状态,其他线程有机会获得 CPU。

不保证,让出 CPU 仅为建议,可能立刻重新调度当前线程执行。

常见用途

实现延时、控制线程速度、模拟定时任务等。

调整线程执行顺序,避免线程长时间占用 CPU。

线程状态

阻塞状态 (Blocked)。

就绪状态 (Ready/Runnable)。

异常处理

需要处理

InterruptedException

不需要异常处理。

锁的影响

保持原有锁。

保持原有锁。

总结

二者都属于Thread类的静态方法,用于控制线程执行状态。Thread.sleep会使线程进入阻塞状态,而Thread.yield 则不会进入阻塞状态,而是让当前线程回到就绪状态。当线程进入阻塞状态之后,在指定的时间结束后才能恢复到可运行状态,因此通常用于固定时间的延迟操作。而当线程进入到就绪状态之后,是否重新获得执行权由JVM决定,因此它更适合调节线程执行顺序而不是实现延时。

在实际应用中,Thread.sleep用于控制时间的暂停,而Thread.yield更适合帮助多线程环境下调度线程执行顺序。

相关文章

Thread.onSpinWait()有什么作用?为什么要睡眠0毫秒?

概述今天在整理之前学习资料时,偶然看见之前自己写的demo:public class MyTest { static volatile boolean temp = true; pu...

Java:代码世界的常青树,就业前景大揭秘

Java:当下依旧火热在当今数字化浪潮中,Java 作为一门经典的编程语言,始终占据着技术舞台的 C 位。先来看一组令人震撼的数据:根据 IDC 统计,全球范围内对 Java 开发工程师的需求竟达到全...

从0到1掌握MyBatis:Java持久层框架的深度解析与实战

一、MyBatis 是什么在 Java 开发的世界里,数据库操作是极为重要的一环。早期,我们使用 JDBC(Java Database Connectivity)来与数据库交互。但随着项目规模的不断扩...

毫秒间查询千亿级Trace数据,SkyWalking上链路追踪这么强?

本文根据张硕老师在〖deeplus直播:平安健康千亿级全链路追踪系统的建设与实践〗线上分享演讲内容整理而成。(文末有回放的方式,不要错过)分享概要一、开篇二、为什么需要全链路监控三、为什么选择SkyW...

哪种编程语言又快又省电?有人对比了27种语言

编辑:小舟、张倩在手机快没电时,管理软件往往会提醒我们关掉某些耗电量高的应用。可见,除了硬件厂商外,软件厂商也应该重视能耗问题。在这篇文章中,研究者分析了一下各种编程语言的能耗对比。当能耗也成为了一个...

「Java」随机数详解_java中随机数语句的规则

在我们的Java课程中通过游戏案例,我们通过随机数来对每次的攻击伤害值进行了一个赋值,那么Java中还有哪些方法可以产生随机数呢?Java中产生随机数的几种方式,随机数的概念从广义上讲,有三种:1、通...