【问题标题】:Java starting, stopping and resuming threadsJava 启动、停止和恢复线程
【发布时间】:2012-05-31 10:54:23
【问题描述】:

我正在使用 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();
    }
}

【问题讨论】:

  • 很可能,您的PlayerThread 实现,无论它是什么,都不知道interrupt 应该会导致它暂停。
  • 问题与GUI无关,与PlayerThread有关。然而,您只向我们展示了 GUI。请阅读 Thread 的 javadoc 以了解这些方法的作用,并注意您不应该使用 resume()。 docs.oracle.com/javase/6/docs/api/java/lang/Thread.html。此外,interrupt() 并不意味着暂停线程。
  • 现在编辑问题。
  • 我为线程 here 提供了暂停/恢复场景的示例代码。它使用ReadWriteLock

标签: java multithreading mp3


【解决方案1】:

您似乎做了很多假设,即事情会“正常工作”,而无需阅读您正在使用的库的 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();
    }
}

【讨论】:

    【解决方案2】:

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

    其次,中断AdvancedPlayer实例的效果不是javadocs定义的。

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


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

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

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


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

    【讨论】:

    • @Twistar:阅读 javadoc。 stop() 已被弃用,不应使用。有文档可供阅读。
    • Thread.stop() 已弃用 (for good reason)。您可以通过在Thread 的实例上调用interrupt() 在线程上设置中断标志。不过,这可能仍然无法满足您的期望/想要的...
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-07
      • 2020-11-22
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多