0
在線查看後,我發現一個類的簡單示例,顯示三個左右線程同時工作。但我似乎無法將其納入我的計劃。我正在製作一個利用數字鍵盤上的按鍵1-9的聲卡,並且在按下時應該播放聲音,但仍允許其他按鍵啓動正在按下的聲音或識別已釋放的聲音並停止播放。但即使(我認爲)我有一個多線程系統設置,一個線程完全控制程序,播放一個音頻文件完成。多線程和聲音問題
這裏是程序的肉:一個簡單的框架,實現Runnable,並在Launcher類中創建和啓動。它具有「圓形」物體,在框架上的數字鍵盤位置顯示一個紅色圓圈,如果按下相應的數字,則會變爲藍色。它還包含一個實現Runnable的SoundButton ArrayList。
框架:
public class Frame extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;
private Pane pane;
private ArrayList<Circle> c;
private ArrayList<SoundButton> SB;
private KeyManager keyManager;
public Frame(ArrayList<SoundButton> soundButton){
keyManager = new KeyManager();
this.addKeyListener(keyManager);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setPreferredSize(new Dimension(400, 400));
this.pack();
this.setLocationRelativeTo(null);
pane = new Pane();
this.add(pane);
c = new ArrayList<Circle>();
SB = soundButton;
c.add(new Circle(20, 140));
c.add(new Circle(80, 140));
c.add(new Circle(140, 140));
c.add(new Circle(20, 80));
c.add(new Circle(80, 80));
c.add(new Circle(140, 80));
c.add(new Circle(20, 20));
c.add(new Circle(80, 20));
c.add(new Circle(140, 20));
this.setVisible(true);
}
public void init(){
pane.draw(c);
}
public void update(){
pane.draw(c);
keyManager.update();
if(keyManager.isNine()){
c.get(8).press();
SB.get(0).start();
}
else{
c.get(8).release();
SB.get(0).stop();
}
if(keyManager.isEight()){
c.get(7).press();
SB.get(1).start();
}
else{
c.get(7).release();
SB.get(1).stop();
}
if(keyManager.isSeven()){
c.get(6).press();
}
else{
c.get(6).release();
}
if(keyManager.isSix()){
c.get(5).press();
}
else{
c.get(5).release();
}
if(keyManager.isFive()){
c.get(4).press();
}
else{
c.get(4).release();
}
if(keyManager.isFour()){
c.get(3).press();
}
else{
c.get(3).release();
}
if(keyManager.isThree()){
c.get(2).press();
}
else{
c.get(2).release();
}
if(keyManager.isTwo()){
c.get(1).press();
}
else{
c.get(1).release();
}
if(keyManager.isOne()){
c.get(0).press();
}
else{
c.get(0).release();
}
}
public void run() {
init();
int fps = 60;
double timePerUpdate = 1000000000/fps;
double delta = 0;
long now;
long lastTime= System.nanoTime();
long timer = 0;
int updates = 0;
while(true){
now = System.nanoTime();
delta += (now - lastTime)/timePerUpdate;
timer+= now - lastTime;
lastTime = now;
if(delta >= 1){
update();
updates ++;
delta--;
}
if(timer >= 1000000000){
//System.out.println("Updates and Frames: "+ updates);
updates = 0;
timer = 0;
}
}
}
}
SoundButton:
public class SoundButton implements Runnable{
private AudioPlayer sound;
private boolean running = false;
private Thread thread;
public SoundButton(String path){
sound = new AudioPlayer(path);
}
@Override
public void run() {
}
public synchronized void start(){
if(running){
return;
}
else{
running = true;
thread = new Thread(this);
thread.start();
sound.play();
}
}
public synchronized void stop(){
if(!running)
return;
running = false;
sound.stop();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
啓動:
public class Launcher {
public static void main(String[] args){
ArrayList<SoundButton> SB = new ArrayList<SoundButton>();
SB.add(new SoundButton("/sound/sound1.mp3"));
SB.add(new SoundButton("/sound/sound2.mp3"));
Frame f = new Frame(SB);
Thread t = new Thread(f);
t.start();
}
}
,如果它是需要的,我的AudioPlayer類:
public class AudioPlayer
{
private clip clip;
public AudioPlayer(String s)
{
try
{
AudioInputStream ais = AudioSystem.getAudioInputStream(
getClass().getResourceAsStream(s));
AudioFormat baseFormat = ais.getFormat();
AudioFormat decodeFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false
);
AudioInputStream dais = AudioSystem.getAudioInputStream(
decodeFormat, ais);
clip = AudioSystem.getClip();
clip.open(dais);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void play()
{
if (clip == null)
{
System.out.print("null");
return;
}
stop();
clip.setFramePosition(0);
clip.start();
System.out.println("Drain...");
clip.drain();
System.out.println("...Drained");
}
public void stop()
{
if (clip.isRunning())
{
clip.stop();
}
}
public void close()
{
stop();
clip.close();
}
}