简体   繁体   中英

Java starting, stopping and resuming threads

I am making a mp3Player in java with the library from javazoom. I have manged to start and stop the mp3 but i cant resume it. Does anyone know how to do this?

Here is the MP3Player class:

public class MP3Player extends JFrame{

public MP3Player(){
    JPanel jpBottom = new JPanel();
    JButton btnPlay = new JButton("Play");
    JButton btnPause = new JButton("Pause");

    jpBottom.add(btnPause);
    jpBottom.add(btnPlay);

    Container cp = this.getContentPane();
    BorderLayout bl = new BorderLayout();
    cp.setLayout(bl);
    cp.add(jpBottom, BorderLayout.SOUTH);

    btnPlay.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if(t.isInterrupted()){
                        t.resume();
                    } else{
                        t.start();
                    }
                }
            }
    );

    btnPause.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e){
                   t.interrupt();
                }
            }
    );

    this.setVisible(true);
    this.setSize(250, 100);
    this.setTitle("MP3 Player");
    this.setLocation(100, 100);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Thread t = new Thread(new PlayerThread("file:///C://a.mp3"));

public static void main(String[] args) {
    MP3Player n = new MP3Player();
}
}

The PlayerThread class:

public class PlayerThread implements Runnable{

    String path;
    PlayerThread(String path){
        this.path = path;
    }

    public void run(){
        try{
            URL url = new URL(path);
            InputStream in = url.openStream();
            AdvancedPlayer pl = new AdvancedPlayer(in);
            pl.play();
        }
        catch(Exception e){
            System.out.println("Error: "+e);
        }
    }

    public void pause(){
        Thread.interrupted();
    }
}

It looks like you're making a lot of assumptions that things will "just work", without reading the APIs for the libraries you're using.

Firstly, interrupting a thread simply sets a flag on that thread. By convention, blocking calls will usually inspect this flag periodically and terminate early by throwing an InterruptedException if that is the case. But that's not an automatic guarantee, and a caller cannot forcibly interrupt another thread. You need to ensure that interruption will do what you expect.

Your pause() method is doubly wrong in that you're not even setting the interrupted flag; Thread.interrupted() checks whether the current thread is interrupted (returning a boolean).

Let's go back to basics - you're playing sound by calling AdvancedPlayer.play() . How do you get an AdvancedPlayer to pause? Looking through its documentation , it seems like it doesn't support pausing in any obvious way. (There's a stop() method but I don't believe it would resume from the same place). And since the method doesn't throw InterruptedException , it's almost guaranteed that it doesn't respond to interrupts .

However, there is a BasicPlayer class that does have a pause. Is there any reason why you couldn't use that instead, something like (ignoring exceptions):

public class PlayerThread implements Runnable{
    final BasicPlayer player;

    PlayerThread(String path){
        player = new BasicPlayer(new URL(path).openStream());
    }

    public void run(){
        player.player();
    }

    public void pause() {
        player.pause();
    }
}

First, fhe Thread.interrupted() tests to see if the thread has been interrupted. It doesn't interrupt it.

Second, the effect of interrupting an AdvancedPlayer instance is not defined by the javadocs.

Third, it looks like the way you are supposed to stop the player is by calling stop() , but there is no specified way to pause.


is that done with Thread.stop()?

Thread.stop() stops the Java thread, but that doesn't mean that the player will stop playing. That depends on how the player library code is implemented.

Furthermore, Thread.stop() is a deprecated API, which can cause all sorts of problems if you use it.


FWIW, the javazoom APIs look a bit of a mess to me, and the libraries don't appear to have been touched for ~10 years. Have you considered looking for something that is more uptodate and better engineered?

First of all you should stop using Thread.suspend and Thread.resume as they are deprecated and deadlock-prone. Instead you should have some sort of flag within PlayerThread eg say isPaused set it to true or false on click on playBtn, based on flag should play or pause the music with playthread.Also please note that once thread becomes dead you can start it again, So i think starting thread within playBtns actionPerformed does not seems good idea ( although im not aware of your entire design)

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