Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am creating a JavaFX application that uses sounds for example for Button hovering. I create an JavaFX AudioClip to create and play the sound. It works ok so far (meaning: I hear the sound).

When the play(); method is called, the sound is played immediatly. If I hover the button 10 times, I hear the sound 10 times. BUT: in the background JavaFX is creating hundreds of threads when the play() method returns (several hundred for each call). I cannot even see what it actually is, because there are so many, Eclipse does not even show them properly (there is just a white area and a crazy jumping scrollbar up and down).

This causes a massive lag and I do not understand what JavaFX is doing here! It is always the same sound, so I do have cached it into a hashmap already, but the problem is not instantiating the AudioClip, it is clearly stacking up when the play() method returns.

I have been looking into this for hours, but I can't figure out a workaround to reduce the lag (other than maybe reduce the size of the soundfiles, which I did).

                final AudioClip soundClip;
                if (audioClipCache.get(url.toString()) != null) {
                    // Log.info("Playing sound from cache...");
                    soundClip = audioClipCache.get(url.toString());
                } else {
                    // Log.info("Caching sound...");
                    soundClip = new AudioClip(url.toString());
                    audioClipCache.put(url.toString(), soundClip);
                }

                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        soundClip.play(soundVolume);
                    }
                });

Forget the hashmap to cache the AudioClips for a moment, that does not make any difference whatsoever. So called the following code, say, 10 times in a row, leads Java to go crazy for about 10 seconds.

                AudioClip soundClip = new AudioClip(url.toString());
                soundClip.play(soundVolume);

That works as it should (as in 5.000.000 examples across the internet), but it produces Threads (and Lag) like crazy after the play(); method is called (several hundred threads per hover / call (as descibed)).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
176 views
Welcome To Ask or Share your Answers For Others

1 Answer

I think you have a problem elsewhere in your code. I've distilled your description down to this (admittedly simplistic) example:

@Override
public void start(Stage arg0) throws Exception
{
    Thread.sleep(10000);

    AudioClip audioClip = new AudioClip(Paths.get("src/main/resources/stackoverflow/audio/alert.wav").toUri().toString());

    for (int i = 0; i < 100; i++)
    {
        int volume = i;
        Platform.runLater(() -> audioClip.play(volume));
        Thread.sleep(10);
    }

    arg0.show();
}

Watching Java Mission Control at the ten second mark, I see 100 threads get created all at once. However, they all immediately die (they've played the short alert sound and are done). So the "Live Thread" graph spikes up by 100 threads and then drops right back to where it was within a couple of seconds.

Is there something elsewhere in your code that is holding onto a resource or a thread reference? That's my best suggestion for trying to find out why you're multiplying.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...