返回

揭秘 notify:它真的能随机唤醒线程吗?

后端

notify 方法:唤醒的奥秘

Java 中的 notify 方法是一个线程通信机制,用于唤醒在某个对象监视器上等待的线程。它不是一个随机唤醒操作,而是根据特定的规则唤醒线程。

线程唤醒机制

当一个线程调用 wait 方法时,它会释放对对象监视器的持有,并进入等待状态。此时,它无法再执行代码。notify 方法唤醒这些等待线程,允许它们继续执行。

notify 的工作原理

notify 方法不会直接唤醒特定线程。相反,它会通知 Java 虚拟机 (JVM),JVM 再负责选择要唤醒的线程。JVM 根据以下规则选择线程:

  • 优先唤醒较长时间等待的线程。 等待时间最长的线程最有可能被唤醒。
  • 如果有多个线程等待时间相同,则JVM 会随机选择一个线程。 因此,notify 方法不是完全随机的,但它可以导致看似随机的唤醒行为。

代码示例

以下是一个代码示例,展示了 notify 方法的工作原理:

public class NotifyExample {
    public static void main(String[] args) {
        Object lock = new Object();

        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("线程1进入等待状态");
                    lock.wait();
                    System.out.println("线程1被唤醒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("线程2进入等待状态");
                    lock.wait();
                    System.out.println("线程2被唤醒");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        thread2.start();

        // 稍等片刻,确保线程1和线程2都进入等待状态
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 唤醒一个等待的线程
        synchronized (lock) {
            lock.notify();
        }
    }
}

运行结果:

线程1进入等待状态
线程2进入等待状态
线程1被唤醒

在这个示例中,两个线程在同一个对象监视器上等待。notify 方法不会随机唤醒线程,而是唤醒了等待时间较长的线程1。

结论

notify 方法不是一个真正的随机唤醒操作。相反,它会根据特定的规则唤醒线程。尽管如此,由于 JVM 在选择线程时考虑了随机性,因此它可能会导致看似随机的唤醒行为。理解 notify 方法的工作原理对于在多线程应用程序中有效地进行线程通信至关重要。