Sim*_*son 3 java eclipse audio multithreading
我在游戏中播放声音时遇到问题.当处理声音播放的线程退出它的run方法时,它不会终止/结束/停止.我知道这是导致问题的方法,因为当我评论整个事情时,不再创建Threads.(使用JVisualVM检查).问题是退出run方法后线程不会被终止.我已经放置了一个print命令来确保它实际到达run()方法的末尾,而且它总是这样.
但是,当我检查进程时JVisualVM,线程数会因1播放的每个声音而增加.我还注意到,1每个播放的声音都增加了守护程序线程的数量.我不确定守护程序的线程是什么以及它们是如何工作的,但我试图以多种方式杀死线程.包括Thread.currentThread .stop() .destroy() .suspend() .interrupt()返回run()方法并从方法返回;
在写这条消息时,我意识到我需要关闭剪辑对象.这导致没有创建和维持额外的线程.然而,现在声音有时会消失,我不知道为什么.现在,我可以有声音并行之间进行选择,看看我的CPU得到由线程数之不尽超载或每当有一个新的声音播放的声音突然终止.
如果有人知道并行播放多个声音的不同方法或知道我的代码有什么问题,我将非常感谢任何帮助.
这是方法:
public static synchronized void playSound(final String folder, final String name) {
new Thread(new Runnable() { // the wrapper thread is unnecessary, unless it blocks on the Clip finishing, see comments
@Override
public void run() {
Clip clip = null;
AudioInputStream inputStream = null;
try{
do{
if(clip == null || inputStream == null)
clip = AudioSystem.getClip();
inputStream = AudioSystem.getAudioInputStream(SoundP.class.getResource(folder + "/" + name));
if(clip != null && !clip.isActive())
inputStream = AudioSystem.getAudioInputStream(SoundP.class.getResource(folder + "/" + name));
clip.open(inputStream);
clip.start();
}while(clip.isActive());
inputStream.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
Run Code Online (Sandbox Code Playgroud)
.stop(),.destroy()或.suspend().这些方法已弃用,不应使用.相反,你应该基本上到达Run()方法的末尾.这Thread.interrupt()是为了什么,但你必须支持通过检查Thread.isInterrupted()标志然后抛出InterruptedException并处理它来中断你的线程(有关更多详细信息,请参阅如何停止线程).do-while循环似乎是多余的.还有其他好方法可以等待声音完成播放(如果这是你的目标),并且循环不是其中之一.一个while没有运行多次的循环Sleep,无缘无故地占用你的CPU.Close()(和 Stop())Clip如您所述,以释放系统资源.尝试运行此代码,看看它是否符合您的要求.我添加了一些线程方法调用和一些System.out.prints,供您查看每一段代码发生的时间.尝试玩tryToInterruptSound和mainTimeOut看看它如何影响输出.
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class PlaySound {
private static boolean tryToInterruptSound = false;
private static long mainTimeOut = 3000;
private static long startTime = System.currentTimeMillis();
public static synchronized Thread playSound(final File file) {
Thread soundThread = new Thread() {
@Override
public void run() {
try{
Clip clip = null;
AudioInputStream inputStream = null;
clip = AudioSystem.getClip();
inputStream = AudioSystem.getAudioInputStream(file);
AudioFormat format = inputStream.getFormat();
long audioFileLength = file.length();
int frameSize = format.getFrameSize();
float frameRate = format.getFrameRate();
long durationInMiliSeconds =
(long) (((float)audioFileLength / (frameSize * frameRate)) * 1000);
clip.open(inputStream);
clip.start();
System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound started playing!");
Thread.sleep(durationInMiliSeconds);
while (true) {
if (!clip.isActive()) {
System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound got to it's end!");
break;
}
long fPos = (long)(clip.getMicrosecondPosition() / 1000);
long left = durationInMiliSeconds - fPos;
System.out.println("" + (System.currentTimeMillis() - startTime) + ": time left: " + left);
if (left > 0) Thread.sleep(left);
}
clip.stop();
System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound stoped");
clip.close();
inputStream.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound interrupted while playing.");
}
}
};
soundThread.setDaemon(true);
soundThread.start();
return soundThread;
}
public static void main(String[] args) {
Thread soundThread = playSound(new File("C:\\Booboo.wav"));
System.out.println("" + (System.currentTimeMillis() - startTime) + ": playSound returned, keep running the code");
try {
Thread.sleep(mainTimeOut );
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tryToInterruptSound) {
try {
soundThread.interrupt();
Thread.sleep(1);
// Sleep in order to let the interruption handling end before
// exiting the program (else the interruption could be handled
// after the main thread ends!).
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("" + (System.currentTimeMillis() - startTime) + ": End of main thread; exiting program " +
(soundThread.isAlive() ? "killing the sound deamon thread" : ""));
}
}
Run Code Online (Sandbox Code Playgroud)
Clip.这样我可以让Thread Sleep()和不使用CPU.我使用一个额外isActive()的测试来看看它是否真的结束了,如果没有 - Sleep()再次计算剩余的时间(Sleep由于两个事实,声音可能仍然在第一个之后播放:1.长度计算不需要微秒考虑到,并且2. "你不能假设调用睡眠会在指定的时间段内暂停线程").| 归档时间: |
|
| 查看次数: |
5434 次 |
| 最近记录: |