如何将java与javascript调用解耦?小程序正在等待自己!
我很难避免小程序中偶尔出现的崩溃,这似乎是由线程本身等待引起的。奇怪的是,这似乎只发生在谷歌浏览器上
30秒阅读:
- 小程序。methodA()调用JSObject。javascriptMethod()
- javascriptMethod()生成一个小程序。methodB()调用
- 小程序。methodB()等待Applet。methodA()来释放它的锁,这永远不会发生李>
我的尝试:
- 在javascriptMethod中使用setTimeout。运气不好李>
- 使用JSObject。eval()而不是JSObject。电话()
也有可能: 我完全误解了线程转储。这是供检查的
我的理解是:
- sequencer线程调用applet。通知位置
- notifyPosition调用javascript方法
- javascript方法调用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)
# 1 楼答案
这里我们看到了一个看起来像问题的部分:
等待
<0x099c50e0>
并不意味着线程等待获取锁,但它拥有锁,并在这个对象上调用了wait()
,这意味着它暂时放弃了锁,并等待其他线程在这个对象上调用.notify()
或.notifyAll()
因此,这个单堆栈跟踪不会显示死锁
当然,从applet到JavaScript和从JavaScript返回applet的实际调用可能在不同的线程上,这可能会显示您描述的行为。但这里的堆栈跟踪似乎并没有表明这一点(我认为alphatab类是您的)
问题很简单,因为某种原因,没有人打电话给
notify()
。可能是同步错误,所以通知实际上是在等待之前发出的。或者其他线程在通知之前正在等待其他锁(这将是一个真正的死锁)