Java 中 wait、sleep 和 yield 的区别

wait

  • wait 是 Object 类的实例方法,用于线程间通信
  • wait() 方法导致当前线程进入等待状态并释放对象的锁,直到它被通知(其他线程调用 notify 或 notifyAll 方法。notify / notifyAll 方法解除等待线程的阻塞状态)
  • wait(long timeout) 方法导致当前线程释放对象的锁,并进入等待状态直到它被通知或者经过指定的时间
  • wait() 和 wait(long timeout) 被唤醒后会进入阻塞状态(Blocked),直到获得锁,才进入就绪态(Runnable)
  • wait() 方法只能在同步方法或同步代码块中调用。如果当前线程不是对象锁的持有者,该方法抛出一个 IllegalMonitorStateException 异常
  • 可以通过 interrupt() 方法打断线程的暂停状态,从而使线程立刻抛出 InterruptedException(但不建议使用该方法),被 interrupt 以后会释放锁
  • 不需要捕获异常

sleep

  • sleep 是 Thread 类的静态方法,作用是阻塞当前线程,让出 CPU 的使用
  • 用于短时间暂停当前线程
  • sleep(long millis) 使当前线程进入停滞状态,所以执行 sleep() 的线程在指定的时间内肯定不会被执行
  • sleep(long millis) 可能使任意优先级的其他线程得到执行机会
  • sleep(long millis) 不会释放锁
  • 调用 sleep 方法的线程在唤醒之后不保证能获取到 CPU,它会先进入就绪态(Runnable),与其他线程竞争 CPU
  • 可以通过 interrupt() 方法打断线程的暂停状态,从而使线程立刻抛出 InterruptedException(但不建议使用该方法),被 interrupt 以后会释放锁
  • 需要捕获异常
/**
 * Thread sleep和wait区别
 */
public class ThreadTest implements Runnable {
    int number = 10;

    public void firstMethod() throws Exception {
        synchronized (this) {
            number += 100;
            System.out.println(number);
        }
    }

    public void secondMethod() throws Exception {
        synchronized (this) {
            /**
             * (休息 2s,阻塞线程)
             * 以验证当前线程对象的机锁被占用时,
             * 是否被可以访问其他同步代码块
             */
            Thread.sleep(2000);
            // this.wait(2000);
            number *= 200;
        }
    }

    @Override
    public void run() {
        try {
            firstMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        ThreadTest threadTest = new ThreadTest();
        Thread thread = new Thread(threadTest);
        thread.start();
        threadTest.secondMethod();
    }
}

运行结果:

Thread.sleep(2000): 2100
this.wait(2000): 110

yield

  • yield 是 Thread 类的静态方法,没有参数,使当前线程从运行状态变为就绪态
  • yield 方法使当前线程让出 CPU,但让出的时间是不可设定的
  • yield 方法不会释放锁
  • yield 会把 CPU 让给相同优先级的其他线程,而不会把 CPU 给更高或更低优先级的其他线程。若此时没有其他线程跟它在有一个优先级,则该线程继续获得 CPU 时间,因此可能某线程刚调用 yield 方法又马上被执行
  • 不需要捕获异常
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容