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

createh53个月前 (03-01)技术教程10

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更适合帮助多线程环境下调度线程执行顺序。

相关文章

Java中获取和处理系统时间的最佳实践

Java中获取和处理系统时间的最佳实践引言在现代软件开发中,时间的处理是一个至关重要的环节。无论是记录日志、生成唯一标识符还是处理并发操作,准确的时间信息都是不可或缺的。Java 提供了多种方式来获取...

全网最全!彻底弄透Java处理GMT/UTC日期时间

作者丨BAT的乌托邦正文平时工作中遇到时间如何处理?用Date还是JDK 8之后的日期时间API?如何解决跨时区转换等等头大问题。A哥向来管生管养,管杀管埋,因此本文就带你领略一下,Java是如何实现...

Java与人工智能:从入门到精通_java转人工智能好转么

Java与人工智能:从入门到精通引言在当今数字化时代,人工智能(AI)已经成为推动技术进步的重要力量。Java作为一种广泛使用的编程语言,以其平台无关性、强大的库支持和丰富的生态系统,在人工智能领域中...

Java并发编程实战:全面指南_java并发编程深度解析

Java并发编程实战:全面指南引言Java并发编程是现代软件开发中不可或缺的一部分,尤其是在处理高并发请求、大规模数据处理和实时系统时。随着多核处理器的普及,充分利用CPU资源成为了提升应用程序性能的...

面试官:讲讲雪花算法,越详细越好

前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯·奈特称,一般的雪花大约由10^19个水分子组成。在雪花形成过程...

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

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