Javaクリップオブジェクトを使用して信号を再生しようとしました。クリップを開始してから、スレッドを続行するまでSTOPイベントが発生するのを待ちます。私は、私のアプリケーションで発生するかもしれない呼び出しスレッドを終了すると、サウンドが再生されない、または最初の部分だけが再生されることが観察されました。ラインリスナーイベントが失われました
ほとんどの場合、これは大変うまくいきますが、約50回ごとに起動され、STARTイベントもSTOPイベントも起動されず、現在のスレッドは永久に待機します。
質問は今私がイベントを緩めさせる同期に何か悪いことをしましたか?ここで
private static volatile boolean isPlaying = false;
private static final Object waitObject = new Object();
public static void playClip(...)
...
Clip clip = (Clip) AudioSystem.getLine(...);
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
event.getLine().close();
synchronized (waitObject) {
isPlaying = false;
waitObject.notifyAll();
}
}
}
});
// start playing clip
synchronized (waitObject) {
isPlaying = true;
}
clip.start();
// keep Thread running otherwise the audio output is stopped when caller thread exits
try {
while (isPlaying) {
synchronized (waitObject) {
waitObject.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
CountDownLatch
を使用して新しいバージョンです:
private static volatile CountDownLatch playingFinished = new CountDownLatch(1);
public static void playClip(...)
...
Clip clip = (Clip) AudioSystem.getLine(...);
clip.open(audioInputStream);
// use line listener to take care of synchronous call
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
event.getLine().close();
playingFinished.countDown();
}
}
});
clip.start();
try {
playingFinished.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
playingFinished = new CountDownLatch(1);
は、私はデバッグ文が含まれていませんでしたが、彼らはSTOPイベントが発生していなかったため、スレッドがplayingFinished.await();
でハングことを示していますplayingFinished.countDown();
は呼び出されません。
私は待機/通知の代わりにCoundDownLatch構成を使用しましたが、問題は依然として残ります。それはJVMに依存しているように思えます。 OpenJDKを使用するとイベントが失われることがありますが、Java Standard Editionを使用すると問題は発生しません。 – Thomas789
変更されたコードを投稿してください。それがjvmに依存している場合は、何か間違っていて動作しているだけで運が良ければ99%です。 –
私は質問を編集し、変更されたコードを掲示しました。これには 'wait/notify'の代わりに' CoundDownLatch'が含まれています。 – Thomas789