简体   繁体   中英

Java thread ending with a delay

I am trying to play mp3's in my java application. The user has the ability to click a button and change the sound.

The sound and switching works...however when a user tries to switch sounds, the new song begins playing over the old one for about a second, before the old one stops playing. I am trying use threads to handle everything.

My MP3 class:

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);}
    }
}

And this is how I attempt to run the code in my main game. The MP3 object is called song.

When the application initializes, the following code is run:

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

somebody tries to change it, the following code is run:

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

Where t is a parameter of the file name.

I'm pretty sure the problem relies in the run function of the MP3 object. I am completely new to threading so I would appreciate some help.

Again, the delay is about 1 second from the time "stop" is called and the time it actually stops playing. So maybe throw a wait in there somewhere?

Thanks!

EDIT: I am using code based off of here now:

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

I have created a play and close function defined as follows:

    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();

My problem is with the close function...the player object is always null and the close function does not execute...even though the play function initializes it. Why is it null?

Edit:

In your edit, if multiple threads are accessing the player field then it should be made volatile . Without seeing how player is defined, it's hard to guess at the problem otherwise.


I think that you will need to make sure that the Player has completed the previous mp3 before you start the next. Looking the javadocs for Player I see:

`player.isComplete()`

To quote:

Returns true if all available MPEG audio frames have been decoded, or false otherwise

If you want to stop the previous audio when the new sound starts you should use close() on the older player.

Closes this player. Any audio currently playing is stopped immediately

Sounds to me that you need to close the current running Player object (if any) and start a new Player object to play the new sound. If you are doing this in multiple threads then you will need to do something like:

  1. lock some final Object lock object
  2. if you want the current sound to finish, check the current Player object (if any) has completed in a loop with sleep
  3. close() the current Player object and create a new Player if you want to kill the current sound
  4. call play() the next mp3,
  5. unlock the lock object.

As far as I know, the play() method does not wait for the sound to be played but returns immediately after loading the sound into the audio buffers. I'm not sure what happens if the audio file is large though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM