You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JDA实现线程等待事件时遭遇IllegalMonitorStateException异常求助

JDA实现线程等待事件时遭遇IllegalMonitorStateException异常求助

兄弟,这问题我太熟了!你碰到的IllegalMonitorStateException完全是因为调用wait()的对象不对,咱们来唠明白:

你代码里用synchronized(lock)拿到了lock对象的锁,但后面直接写wait()的时候,这个wait()其实是调用当前匿名Thread实例的wait()方法(相当于this.wait()),可你根本没持有这个Thread对象的锁啊!Java里有明确规定:必须在当前线程持有锁的那个对象上调用wait()/notify()系列方法,不然铁定抛这个异常。

修正方案超简单:

把代码里的wait()改成lock.wait()就行!因为你同步的是lock,所以必须在lock对象上调用wait(),这样才符合锁的持有规则。同理,要是后面你要唤醒这个线程,也得在lock对象上调用lock.notify()或者lock.notifyAll(),而且唤醒的时候也得先持有lock的锁哦。

修正后的核心代码片段如下:

public void waitForMethod () {
    Thread thread = new Thread() {
        @Override
        public void run () {
            synchronized(lock) {
                while (true) {
                    if (methodDone) {
                        methodDone = false;
                        channel.sendMessage("methodDone = true").queue();
                        break;
                    } else {
                        channel.sendMessage("methodDone = false").queue();
                        try {
                            lock.wait(); // 这里改成lock.wait()
                            channel.sendMessage("successfully notified.").queue();
                        } catch (InterruptedException e) {
                            // 建议这里处理中断,比如退出循环,避免线程挂死
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                }
            }
        }
    };
    thread.start();
}

另外多嘴提一句,JDA本身是事件驱动模型,其实你可以考虑用CompletableFuture或者监听JDA的特定事件来实现等待逻辑,这样比手动管理线程锁要更优雅,不过先把当前的异常解决掉再说~

备注:内容来源于stack exchange,提问作者xXSpaghett69Xx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:49:33