java - 如何将 java 与 javascript 调用分离?小程序正在等待自己!

标签 java javascript google-chrome liveconnect

我无法避免我的小程序中的偶发崩溃,这似乎是由线程自身等待引起的。奇怪的是,这似乎只发生在谷歌浏览器中。

30 秒阅读:

  • Applet.methodA() 调用 JSObject.javascriptMethod()
  • javascriptMethod() 调用 Applet.methodB()
  • Applet.methodB() 等待 Applet.methodA() 释放它的锁,这从来没有发生过..

我尝试过的:

  • 在 javascriptMethod 中使用 setTimeout。运气不好。
  • 使用 JSObject.eval() 而不是 JSObject.call()

也可能: 我完全误解了线程转储。这是为了检查。

我的理解:

  1. 定序器线程调用applet.notifyPosition
  2. notifyPosition 调用 javascript 方法
  3. javascript 方法调用 applet.pause
  4. applet.pause 需要锁定 sequencer,但不能,因为它正忙于调用 notifyposition..

    "Java Sound Sequencer" prio=8 tid=0x189de400 nid=0x86c in Object.wait() [0x1c6ae000]
       java.lang.Thread.State: TIMED_WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x099c50e0> (a java.lang.Object)
            at com.sun.media.sound.RealTimeSequencer$PlayThread.stop(Unknown Source)
            - locked <0x099c50e0> (a java.lang.Object)
            - locked <0x099c50e8> (a com.sun.media.sound.RealTimeSequencer$PlayThread)
            at com.sun.media.sound.RealTimeSequencer.implStop(Unknown Source)
            at com.sun.media.sound.RealTimeSequencer.stop(Unknown Source)
            - locked <0x099c8ca8> (a com.sun.media.sound.RealTimeSequencer)
            at net.alphatab.midi.MidiPlayer.pause(Unknown Source)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
            at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
            at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
            at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
            at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
            at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
            at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
            at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
            at sun.plugin2.main.client.LiveConnectSupport.doObjectOp(Unknown Source)
            at sun.plugin2.main.client.MessagePassingJSObject.waitForReply(Unknown Source)
            at sun.plugin2.main.client.MessagePassingJSObject.call(Unknown Source)
            at net.alphatab.midi.MidiPlayer.notifyPosition(Unknown Source)
            at net.alphatab.midi.MidiPlayer.access$200(Unknown Source)
            at net.alphatab.midi.MidiPlayer$1.controlChange(Unknown Source)
            at net.alphatab.midi.TickNotifierReceiver.send(Unknown Source)
            at com.sun.media.sound.AbstractMidiDevice$TransmitterList.sendMessage(Unknown Source)
            - locked <0x0982d8e8> (a java.util.ArrayList)
            at com.sun.media.sound.RealTimeSequencer$DataPump.dispatchMessage(Unknown Source)
            at com.sun.media.sound.RealTimeSequencer$DataPump.pump(Unknown Source)
            - locked <0x09a56ae8> (a com.sun.media.sound.RealTimeSequencer$DataPump)
            at com.sun.media.sound.RealTimeSequencer$PlayThread.run(Unknown Source)
            at java.lang.Thread.run(Unknown Source)
    

最佳答案

这里我们看到了看起来有问题的部分:

"Java Sound Sequencer" prio=8 tid=0x189de400 nid=0x86c in Object.wait() [0x1c6ae000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x099c50e0> (a java.lang.Object)
        at com.sun.media.sound.RealTimeSequencer$PlayThread.stop(Unknown Source)
        - locked <0x099c50e0> (a java.lang.Object)

等待<0x099c50e0> 并不意味着线程等待获得锁,但它已经获得了锁,并调用了wait()。在这个对象上,意味着它暂时放弃了锁并等待直到其他线程调用 .notify().notifyAll()在同一个对象上。

因此,这个单一堆栈跟踪没有显示死锁。

当然,从小程序到 JavaScript 的实际调用以及从 JavaScript 返回到小程序的实际调用可能在不同的线程上,这可能会显示您描述的行为。但是你在这里的堆栈跟踪似乎并没有表明这一点(我想 alphatab 类是你的)。

问题很简单,就是没有人在调用 notify()因为某些原因。也许有一些同步错误,所以通知实际上是在等待之前。或者其他一些线程在通知之前正在等待其他一些锁(这将是一个真正的死锁)。

关于java - 如何将 java 与 javascript 调用分离?小程序正在等待自己!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6804643/

相关文章:

java - 在 AWS Lambda 中使用自定义类时出现 JSON 解析错误

java - 如何在小程序中的 JPanel 之间切换?

javascript - 删除 chrome 扩展中的 chrome.alarms 监听器

javascript - 在 ExtJS 中动态更改组件

javascript - 这个对象在 promise 中

javascript - 脚本执行暂停时如何在chrome devtools中运行异步代码?

java - 替代 Thread.suspend() 和 .resume()

java - 加密是否保留 Base64 编码

html - Chrome 78.0.3904.70 上出现 "white-space: nowrap"问题

javascript - 在 Chrome 中打开多个窗口/选项卡