簡體   English   中英

Java啟動,停止和恢復線程

[英]Java starting, stopping and resuming threads

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

看起來你做了很多假設,事情會“正常工作”,而不會閱讀你正在使用的庫的API。

首先,中斷線程只是在該線程上設置一個標志。 按照慣例,阻塞調用通常會定期檢查此標志,並在發生InterruptedException時提前終止(如果是這種情況)。 但這不是自動保證,並且調用者不能強行中斷另一個線程。 您需要確保中斷能夠達到預期效果。

你的pause()方法是錯誤的,因為你甚至沒有設置中斷的標志; Thread.interrupted() 檢查當前線程是否被中斷(返回布爾值)。

讓我們回到基礎 - 你通過調用AdvancedPlayer.play()來播放聲音。 你如何讓AdvancedPlayer暫停? 查看其文檔 ,似乎它不支持以任何明顯的方式暫停。 (有一個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();
    }
}

首先,使用Thread.interrupted()測試線程是否被中斷。 它不會打斷它。

其次,javadocs沒有定義中斷AdvancedPlayer實例的效果。

第三, 看起來你應該通過調用stop()停止播放器的方式,但是沒有指定的方法可以暫停。


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

Thread.stop()停止Java線程,但這並不意味着播放器將停止播放。 這取決於玩家庫代碼的實現方式。

此外, Thread.stop()是一個不推薦使用的API,如果您使用它可能會導致各種問題。


FWIW,javazoom API對我來說看起來有點混亂,而且這些庫似乎已經被觸及了大約10年。 你有沒有考慮過尋找更新,更好的設計?

首先,您應該停止使用Thread.suspend和Thread.resume,因為它們已被棄用並且容易出現死鎖。 相反,你應該在PlayerThread中有一些標志,例如說isPaused將它設置為true或false,點擊playBtn,基於flag應播放或暫停playthread音樂。另請注意,一旦線程變為死,你可以再次啟動它,所以我認為在playBtns actionPerformed中啟動線程似乎不太好主意(雖然我不知道你的整個設計)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM