1

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

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 需要锁定定序器,但不能,因为它正忙于调用 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)
    
4

1 回答 1

3

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

"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()在同一个对象上。

因此,这个单一的堆栈跟踪不会显示死锁。

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

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

于 2011-07-24T03:11:43.127 回答