如何在完成播放后立即高效关闭大量剪辑?

时间:2018-05-16 19:41:58

标签: java

我有一个使用这种方法播放声音效果的游戏:

 AudioInputStream inputStream = AudioSystem.getAudioInputStream(
          TheGame.class.getResource(url));
          Clip clip = AudioSystem.getClip();


           clip.open(inputStream);
           clip.start(); 

但是,不关闭剪辑显然会增加内存,我尝试过的修复程序会导致游戏偶尔冻结。 我试过了:

  1. 为每个剪辑在剪辑停止时关闭剪辑创建一个新的LineListener。冻结游戏OFTEN。
  2. 让一个LineListener侦听停止时关闭它们的每个剪辑。经常冻结。
  3. 与#2相同,但是在多个LineListeners之间划分剪辑,我尝试了4,6和10,并且所有游戏都至少冻结了一次。
  4. 永远不要关闭剪辑,最终游戏将停止播放声音并冻结
  5. 在剪辑打开后立即设置为空,与#4
  6. 的结果相同

    我不确定为什么关闭剪辑似乎需要花费很多时间来冻结整个游戏,是否有更节省时间的方式?

    以下是使用LineListener更新方法的代码:

        @Override
    public void update(LineEvent event) {
         if (event.getType() == LineEvent.Type.STOP){
                   Clip c = (Clip) event.getSource();
                   c.close();
                   c.removeLineListener(this);
         }
    }
    

1 个答案:

答案 0 :(得分:3)

根据我上面的评论,您应该重用现有的Map<String, Clip> clips = new HashMap<String, Clip>(); public synchronized void play(String url) { Clip clip = clips.get(url); if(clip == null) { AudioInputStream inputStream = AudioSystem.getAudioInputStream( TheGame.class.getResource(url)); Clip clip = AudioSystem.getClip(); clip.open(inputStream); clips.put(url, clip); } if(clip.isRunning()) clip.stop(); clip.setFramePosition(0); clip.start(); } 对象。

synchronized

如果您需要将相同的声音与自身重叠,则需要更具创意。请注意,我已将其置于Map方法中,以保护data()不会发生并发修改,如果您碰巧从多个线程调用此方法。