使用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
相关产品推荐
相关产品推荐

