Java 守护进程线程过多会导致程序失败

Java 守护进程线程过多会导致程序失败,java,multithreading,Java,Multithreading,我正在写一个模拟打鼓的程序。你坐在摄像机前,点击一个预定义的点,程序就会播放一些声音。有不止一个鼓,所以我必须在多线程中执行它,这样人们可以同时演奏两个鼓(就像现实生活中可能发生的那样)。我播放音乐的方法如下所示: void playInstrumentSound(InstrumentModel instrument) { System.out.println("Playing: " + instrument.getInstrumentName()); if (instrume

我正在写一个模拟打鼓的程序。你坐在摄像机前,点击一个预定义的点,程序就会播放一些声音。有不止一个鼓,所以我必须在多线程中执行它,这样人们可以同时演奏两个鼓(就像现实生活中可能发生的那样)。我播放音乐的方法如下所示:

void playInstrumentSound(InstrumentModel instrument) {

    System.out.println("Playing: " + instrument.getInstrumentName());
    if (instrument.getMedia() != null) {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                instrument.setPlaying(true);
                MediaPlayer player = new MediaPlayer(instrument.getMedia());
                player.setVolume(instrument.getVolume());
                player.play();
                try {
                    Thread.sleep(sleepLength);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instrument.setPlaying(false);
            }
        });
        t.start();

    }
}
参数是我的工具模型,这里有一个构造函数:

public InstrumentModel(String instrumentName, float[] coordinates, String pathToSound, float diameter, float addToSpineX,
        float addToSpineY, float addToSpineZ) {
    this.instrumentName = instrumentName;
    this.coordinates = coordinates;
    this.pathToSound = pathToSound;
    this.diameter = diameter;
    this.addToSpineX = addToSpineX;
    this.addToSpineY = addToSpineY;
    this.addToSpineZ = addToSpineZ;

    this.leftHandHighestDistance = 0;
    this.rightHandHighestDistance = 0;
    this.volume = 0;

    this.leftHandMovingCloser = false;
    this.rightHandMovingCloser = false;

    if (this.pathToSound != null) {
        media = new Media(new File(this.pathToSound).toURI().toString());
        setMedia(media);
    }
}
在这种情况下,最重要的是通往声音的途径。我所有的声音都在
src/main/resources
中,当我创建一个对象时,我会传递类似
src/main/resources/snareDrum.wav的消息。基于此路径,它创建媒体对象
(来自javafx.scene.Media)
,以便在播放音乐的方法中可以使用它。它工作得很好,但问题是过了一段时间,我仍然可以看到
播放:…
当我击鼓时,但程序不再播放声音。它总是发生在说
Timer-62
的线程之后。你可以在下面看到:


每次我敲鼓都会创建两个线程——一个来自JFXMedia,另一个写着“Timer xx”。就像我说的,在一个叫“Timer-62”的节目之后,我再也听不到声音了。你知道为什么会这样吗?提前谢谢。

我的假设是,当
MediaPlayer.play一直在后台运行时,线程永远不会退出。播放结束后,尝试手动关闭它-这可能会有所帮助。我的第一个假设是,在您创建的每个线程中创建一个新的
MediaPlayer
对象是问题所在。您是否尝试过保留这些内容,并检查当前媒体是否已经有了这些内容,并重复使用这些内容,而不是每次都创建一个新的内容?@Ben手动关闭意味着什么?我尝试了Thread.currentThread().interrupt()之类的方法,但实际上它并没有停止线程。因为.stop()已被弃用,所以不要有任何其他想法。@daniu我可以在获取声音路径后立即尝试在InstrumentModel类中创建MediaPlayer对象。我想我以前试过,但它不起作用,但我会再试一次。Thanks@JakubBoruk调用
interrupt
stop
(正如您正确指出的那样,这是不推荐的)并不会“停止”线程,它只是发送一个信号,该线程可以捕捉到该信号以决定它现在将要关闭。但是,您可以尝试在MediaPlayer上调用
dispose
,这将释放分配给它的所有资源,并应打开线程停止。