Java线程以延迟结束

时间:2012-04-17 05:00:32

标签: java eclipse multithreading javasound

我正在尝试在我的java应用程序中播放mp3。用户可以单击按钮并更改声音。

声音和切换工作......但是当用户试图切换声音时,新歌开始播放旧歌曲大约一秒钟,然后旧歌曲停止播放。我正在尝试使用线程来处理所有事情。

我的MP3课程:

import java.applet.*;
import javazoom.jl.player.Player;
import java.io.*;
import java.io.FileInputStream;
import java.net.*;

public class mp3 extends Thread implements Runnable{

    private Player sound;
    private InputStream path;  
    public mp3(String file_name) {
        path = mp3.class.getClassLoader().getResourceAsStream(file_name);  
    }
    public void run(){
        try {
            Player sound=new Player(path);
            sound.play();
        } catch(Exception e) {System.out.println(e);}
    }
}

这就是我尝试在主游戏中运行代码的方式。 MP3对象称为歌曲。

当应用程序初始化时,运行以下代码:

song = new mp3("default.mp3");
song.start();

有人试图更改它,运行以下代码:

song.stop();
song = new mp3(t+".mp3");
song.start();

其中t是文件名的参数。

我很确定问题依赖于MP3对象的运行功能。我对线程是全新的,所以我会感激一些帮助。

同样,从“停止”被调用的时间到实际停止播放的时间,延迟约为1秒。那么也许在那里等一下?

谢谢!

编辑:我现在正在使用此处的代码:

  

http://introcs.cs.princeton.edu/java/faq/mp3/MP3.java.html

我创建了一个play和close函数,定义如下:

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        } catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

        // run in new thread to play in background
        new Thread() {
            public void run() {
                try { player.play(); }
                catch (Exception e) { System.out.println(e); }
            }
        }.start();

我的问题是关闭函数...播放器对象总是为null而close函数不执行...即使play函数初始化它。为什么它是空的?

1 个答案:

答案 0 :(得分:1)

修改

在您的编辑中,如果多个线程正在访问player字段,那么应该将其设为volatile。在没有看到如何定义player的情况下,很难再猜出这个问题。


我认为您需要确保Player在开始下一个之前已经完成了之前的mp3。看javadocs for Player我看到了:

`player.isComplete()`

引用:

  

如果所有可用的MPEG音频帧都已解码,则返回true,否则返回

如果您想在新声音开始时停止上一个音频,则应在旧播放器上使用close()

  

关闭此播放器。当前播放的任何音频都会立即停止

听起来你需要关闭当前正在运行的Player对象(如果有的话)并启动一个新的Player对象来播放新声音。如果您在多个线程中执行此操作,则需要执行以下操作:

  1. 锁定一些final Object lock对象
  2. 如果您希望当前声音完成,请检查当前Player对象(如果有)已在sleep
  3. 循环中完成
  4. close()当前Player对象,如果您想杀死当前声音,请创建一个新Player
  5. 拨打play()下一个mp3,
  6. 解锁锁定对象。
  7. 据我所知,play()方法不会等待播放声音,而是在将声音加载到音频缓冲区后立即返回。我不确定如果音频文件很大会发生什么。