简体   繁体   English

Java启动,停止和恢复线程

[英]Java starting, stopping and resuming threads

I am making a mp3Player in java with the library from javazoom. 我正在使用javazoom中的库在java中创建一个mp3Player。 I have manged to start and stop the mp3 but i cant resume it. 我已经开始和停止MP3但我无法恢复它。 Does anyone know how to do this? 有谁知道如何做到这一点?

Here is the MP3Player class: 这是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();
}
}

The PlayerThread class: 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();
    }
}

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. 看起来你做了很多假设,事情会“正常工作”,而不会阅读你正在使用的库的API。

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. 按照惯例,阻塞调用通常会定期检查此标志,并在发生InterruptedException时提前终止(如果是这种情况)。 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; 你的pause()方法是错误的,因为你甚至没有设置中断的标志; Thread.interrupted() checks whether the current thread is interrupted (returning a boolean). Thread.interrupted() 检查当前线程是否被中断(返回布尔值)。

Let's go back to basics - you're playing sound by calling AdvancedPlayer.play() . 让我们回到基础 - 你通过调用AdvancedPlayer.play()来播放声音。 How do you get an AdvancedPlayer to pause? 你如何让AdvancedPlayer暂停? 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). (有一个stop()方法,但我不相信它会从同一个地方恢复)。 And since the method doesn't throw InterruptedException , it's almost guaranteed that it doesn't respond to interrupts . 并且由于该方法不会抛出InterruptedException ,因此几乎可以保证它不会响应中断

However, there is a BasicPlayer class that does have a pause. 但是,有一个BasicPlayer类确实有一个暂停。 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. 首先,使用Thread.interrupted()测试线程是否被中断。 It doesn't interrupt it. 它不会打断它。

Second, the effect of interrupting an AdvancedPlayer instance is not defined by the javadocs. 其次,javadocs没有定义中断AdvancedPlayer实例的效果。

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. 第三, 看起来你应该通过调用stop()停止播放器的方式,但是没有指定的方法可以暂停。


is that done with Thread.stop()? 是用Thread.stop()完成的吗?

Thread.stop() stops the Java thread, but that doesn't mean that the player will stop playing. Thread.stop()停止Java线程,但这并不意味着播放器将停止播放。 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. 此外, Thread.stop()是一个不推荐使用的API,如果您使用它可能会导致各种问题。


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. FWIW,javazoom API对我来说看起来有点混乱,而且这些库似乎已经被触及了大约10年。 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. 首先,您应该停止使用Thread.suspend和Thread.resume,因为它们已被弃用并且容易出现死锁。 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) 相反,你应该在PlayerThread中有一些标志,例如说isPaused将它设置为true或false,点击playBtn,基于flag应播放或暂停playthread音乐。另请注意,一旦线程变为死,你可以再次启动它,所以我认为在playBtns actionPerformed中启动线程似乎不太好主意(虽然我不知道你的整个设计)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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