MST

星途 面试题库

面试题:Java线程生命周期中,处于WAITING状态的线程如何唤醒?

在Java线程生命周期里,线程进入WAITING状态后,通常有哪些方法可以将其唤醒?请举例说明使用场景及相关代码实现。
11.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在Java线程生命周期中,线程进入WAITING状态后,通常有以下几种方法可以将其唤醒:

  1. 使用notify()notifyAll()方法:这两个方法是定义在Object类中的,用于唤醒等待在该对象监视器上的线程。notify() 方法随机唤醒一个等待在该对象监视器上的线程,而 notifyAll() 方法唤醒所有等待在该对象监视器上的线程。

    使用场景:当某个线程完成了特定任务,需要通知其他等待该任务完成的线程继续执行时,就可以使用 notify()notifyAll() 方法。

    代码示例

    public class WaitNotifyExample {
        private static final Object lock = new Object();
    
        public static void main(String[] args) {
            Thread waitingThread = new Thread(() -> {
                synchronized (lock) {
                    try {
                        System.out.println("Waiting thread is waiting...");
                        lock.wait();
                        System.out.println("Waiting thread has been notified.");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            Thread notifyingThread = new Thread(() -> {
                synchronized (lock) {
                    System.out.println("Notifying thread is doing some work...");
                    // 模拟一些工作
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.notify();
                    System.out.println("Notifying thread has notified the waiting thread.");
                }
            });
    
            waitingThread.start();
            notifyingThread.start();
        }
    }
    
  2. 使用LockSupport类的unpark(Thread thread)方法LockSupport类提供了更细粒度的线程阻塞和唤醒操作。unpark(Thread thread) 方法用于唤醒指定的线程。

    使用场景:在一些需要更灵活控制线程唤醒的场景中,例如实现自定义的同步机制或线程协作时,LockSupport 更为适用。

    代码示例

    import java.util.concurrent.locks.LockSupport;
    
    public class LockSupportExample {
        public static void main(String[] args) {
            Thread waitingThread = new Thread(() -> {
                System.out.println("Waiting thread is waiting...");
                LockSupport.park();
                System.out.println("Waiting thread has been unparked.");
            });
    
            Thread unparkingThread = new Thread(() -> {
                System.out.println("Unparking thread is doing some work...");
                // 模拟一些工作
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LockSupport.unpark(waitingThread);
                System.out.println("Unparking thread has unparked the waiting thread.");
            });
    
            waitingThread.start();
            unparkingThread.start();
        }
    }