You need to enable JavaScript to run this app. 调用wait()进入等待的Java线程能否自行调用notify()唤醒自己?
优惠活动
大模型
产品
解决方案
定价
更多

调用wait()进入等待的Java线程能否自行调用notify()唤醒自己?

Java自定义线程挂起/等待实现逻辑答疑

示例代码

// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
    String name; // name of thread
    Thread t;
    boolean suspendFlag;
    NewThread(String threadname) {
        name = threadname;
        t = new Thread(this, name);
        System.out.println("New thread: " + t);
        suspendFlag = false;
        t.start(); // Start the thread
    }
    // This is the entry point for thread.
    public void run() {
        try {
            for (int i = 15; i > 0; i--) {
                System.out.println(name + ": " + i);
                Thread.sleep(200);
                synchronized(this) {
                    while (suspendFlag) {
                        wait();
                    }
                }
            }
        } catch (InterruptedException e) {
            System.out.println(name + " interrupted.");
        }
        System.out.println(name + " exiting.");
    }
    void mysuspend() {
        suspendFlag = true;
    }
    synchronized void myresume() {
        suspendFlag = false;
        notify();
    }
}
class SuspendResume {
    public static void main(String args[]) {
            NewThread ob1 = new NewThread("One");
            NewThread ob2 = new NewThread("Two");
            try {
                Thread.sleep(1000);

                ob1.mysuspend();

                System.out.println("Suspending thread One");

                Thread.sleep(1000);

                ob1.myresume();
                // 后续代码省略

核心理解偏差说明

你产生疑问的根本原因是混淆了执行方法的线程主体:
调用ob1.mysuspend()、ob1.myresume()的是main主线程,而处于等待队列阻塞的是ob1实例关联的子线程ob1.t,二者是完全独立的两个执行流,不存在「阻塞线程自己调用方法唤醒自己」的逻辑。

实际运行机制完整流程

我们以ob1的生命周期为例,完整执行逻辑如下:

  • 实例化ob1时,会自动启动子线程ob1.t,该子线程独立执行run方法中的循环逻辑
  • main线程调用ob1.mysuspend():该方法无同步修饰,直接修改成员变量suspendFlag = true,执行过程不需要拿锁,瞬间完成
  • ob1.t执行到run方法中的synchronized(this)代码块时,先拿到ob1实例的对象锁,判断suspendFlag为true后调用wait():调用wait方法的瞬间,ob1.t会自动释放持有的ob1对象锁,之后进入ob1实例的等待队列阻塞,此时ob1的对象锁回到空闲状态
  • main线程调用ob1.myresume():该方法为同步方法,需要先获取ob1实例的对象锁,由于此时锁是空闲的,main线程可以直接拿到锁,先修改suspendFlag = false,再调用notify()唤醒等待队列中的ob1.t,方法执行完成后main线程自动释放ob1的对象锁
  • 被唤醒的ob1.t会重新竞争ob1的对象锁,拿到锁后会退出while循环,继续执行后续的循环逻辑

补充注意点

该示例为了简化演示省略了安全处理,实际生产中使用需要给mysuspend方法也增加synchronized修饰,或者给suspendFlag变量加volatile修饰,避免多线程环境下的可见性问题。

内容的提问来源于stack exchange,提问作者stkUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 08:06:03