Java启动,停止和恢复线程

时间:2012-05-31 10:54:24

标签: java multithreading mp3

我正在使用javazoom中的库在java中创建一个mp3Player。我已经开始和停止MP3但我无法恢复它。有谁知道怎么做?

这是MP3Player类:

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

PlayerThread类:

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

3 个答案:

答案 0 :(得分:3)

看起来你做了很多关于事情“只是工作”的假设,而没有阅读你正在使用的库的API。

首先,中断线程只是在该线程上设置一个标志。按照惯例,阻塞调用通常会定期检查此标志,并在发生InterruptedException时提前终止(如果是这种情况)。但这不是自动保证,并且调用者不能强行中断另一个线程。您需要确保中断能够达到预期效果。

你的pause()方法是错误的,因为你甚至没有设置中断的标志; Thread.interrupted() 检查当前线程是否被中断(返回布尔值)。

让我们回到基础 - 你通过拨打AdvancedPlayer.play()来播放声音。你如何让AdvancedPlayer暂停?通过它的documentation,它似乎不支持以任何明显的方式暂停。 (有一个stop()方法,但我不相信它会从同一个地方恢复)。由于该方法不会抛出InterruptedException,因此几乎可以保证不会响应中断

但是,有一个BasicPlayer类确实有暂停。你有什么理由不能使用它,比如(忽略例外):

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

答案 1 :(得分:1)

首先,Thread.interrupted()测试线程是否被中断。它不会打断它。

其次,javadocs没有定义中断AdvancedPlayer实例的效果。

第三,看起来像你应该通过调用stop()来阻止播放器的方式,但是没有指定的暂停方式。


  

是用Thread.stop()完成的吗?

Thread.stop()停止Java线程,但这并不意味着播放器将停止播放。这取决于玩家库代码的实现方式。

此外,Thread.stop()是一个弃用的API,如果您使用它会导致各种问题。


FWIW,javazoom API对我来说看起来有点混乱,而且这些库似乎已经被触及了大约10年。您是否考虑过寻找更新,更好的设计?

答案 2 :(得分:0)

首先,您应该停止使用Thread.suspend和Thread.resume,因为它们已被弃用并且容易出现死锁。相反,你应该在PlayerThread中有一些标志,例如isPaused 单击playBtn将其设置为true或false,基于flag应该播放或暂停playthread的音乐。另请注意,一旦线程变为死,你可以再次启动它,所以我觉得playBtns actionPerformed中的起始线程似乎不太好主意(虽然我不知道你的整个设计)