问题已经解决,大家不用回答了。。。见一楼评论
我的程序里需要播放很多个短的声音片段,运行中偶尔会出现几秒钟的卡顿没有声音,一两秒之后突然所有卡住的声音一起出来。。我一开始怀疑是线程之间冲突了,然后用cachedthreadpool来管理,然而问题依旧,而且通过监测线程池的状态发现问题在于某一个时刻其中一个线程执行到ac.play时卡住了,于是线程池收到下一个播放任务时不得不开启新的线程,线程池中的线程数量也不断累积但是都卡在执行ac.play这一步,过了一两秒突然所有线程的“阻塞”都通了,声音也同时播放出来。
不知道问题的症结到底在哪里,尝试了很长时间一直没有解决,非常苦恼。。。
import java.applet.Applet;
import java.applet.AudioClip;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SoundEffect implements Runnable {
private static final ExecutorService exec = Executors.newCachedThreadPool();
private static final int dulplinum = 10;
private static AudioClip[]
ac1 = new AudioClip[dulplinum],
ac2 = new AudioClip[dulplinum],
ac3 = new AudioClip[dulplinum],
ac4 = new AudioClip[dulplinum],
ac5 = new AudioClip[dulplinum],
ac6 = new AudioClip[dulplinum],
ac7 = new AudioClip[dulplinum],
ac8 = new AudioClip[dulplinum],
ac9 = new AudioClip[dulplinum],
ac10 = new AudioClip[dulplinum],
ac11 = new AudioClip[dulplinum];
private static AudioClip[][] acarray = {ac1,ac2,ac3,ac4,ac5,ac6,ac7,ac8,ac9,ac10,ac11};
private static String[] acname = {"move","lock","select","hold","rotate","decide","levelup","erase","lose","harddrop","pause"};
static{
for(int i=0;i<acarray.length;i++) {
for(int j=0;j<dulplinum;j++) {
acarray[i][j] = Applet.newAudioClip(SoundEffect.class.getResource("/resources/sound/"+acname[i]+".wav"));
}
}
}
private static Integer[] cursorArray = {0,0,0,0,0,0,0,0,0,0,0};
private int cursor;
private AudioClip ac;
private String name;
SoundEffect(String name) {
this.name = name;
}
public void run() {
switch(name) {
case "move": cursor = 0; break;
case "lock": cursor = 1; break;
case "select": cursor = 2; break;
case "hold": cursor = 3; break;
case "rotate": cursor = 4; break;
case "decide": cursor = 5; break;
case "levelup": cursor = 6; break;
case "erase": cursor = 7; break;
case "lose": cursor = 8; break;
case "harddrop":cursor = 9; break;
case "pause": cursor = 10;break;
}
ac = cursor2ac(cursor);
ac.play();
}
private static synchronized AudioClip cursor2ac(int cursor) {
cursorArray[cursor] = (cursorArray[cursor]+1)%dulplinum;
return acarray[cursor][cursorArray[cursor]];
}
public static void playSound(String name) {
exec.execute(new SoundEffect(name));
}
}
稍微解释一下,dulplinum=10 的意思是每个ac都缓存10份,每一个新的进程会循环地从4份中取出其中一个来播放。
下面这个就是卡顿发生时,相关信息输出到控制台的结果。
[time: 0] Sound: move 第0个副本
[time: 192] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 2, active threads = 1, queued tasks = 0, completed tasks = 439]
[time: 0] Sound: move 第1个副本
[time: 197] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 2, active threads = 1, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: move 第2个副本
[time: 91] play sound rotate
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: rotate 第1个副本
[time: 272] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 440]
[time: 1] Sound: move 第3个副本
[time: 303] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 4, active threads = 4, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: move 第4个副本
[time: 48] play sound harddrop
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 5, active threads = 5, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: harddrop 第8个副本
[time: 50] play sound lock
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 6, active threads = 6, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: lock 第8个副本
[time: 182] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 7, active threads = 7, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: move 第5个副本
[time: 120] play sound move
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 8, active threads = 8, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: move 第6个副本
[time: 216] play sound rotate
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 9, active threads = 9, queued tasks = 0, completed tasks = 440]
[time: 0] Sound: rotate 第2个副本
[time: 1528] play sound pause
[time: 0] java.util.concurrent.ThreadPoolExecutor@22d9a984[Running, pool size = 9, active threads = 1, queued tasks = 0, completed tasks = 449]
[time: 0] Sound: pause 第3个副本
[time:21429] bgm end