Как я могу отделить Java к вызовам JavaScript?Апплет ждет себя! - PullRequest
1 голос
/ 24 июля 2011

У меня проблемы с предотвращением случайного сбоя в моем апплете, который, по-видимому, вызван потоком, ожидающим самого себя. Как ни странно, это, кажется, происходит только в Google Chrome.

30 секунд чтения:

  • Applet.methodA () вызывает JSObject.javascriptMethod ()
  • javascriptMethod () выполняет вызов Applet.methodB ()
  • Applet.methodB () ожидает, пока Applet.methodA () освободит свою блокировку, что никогда не происходит ..

Что я пробовал:

  • с использованием setTimeout в javascriptMethod. не повезло.
  • с использованием 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)
    

1 Ответ

3 голосов
/ 24 июля 2011

Здесь мы видим часть, которая выглядит как проблема:

"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(). Возможно, произошла какая-то ошибка синхронизации, поэтому уведомление пришло раньше ожидания. Или какой-то другой поток ожидает уведомления о какой-либо другой блокировке (это будет настоящая мертвая блокировка).

...