JLayer暂停并恢复

时间:2013-07-19 22:32:31

标签: java multithreading audio mp3 jlayer

我刚开始使用Jlayer库播放MP3。它完美无缺,我可以播放这首歌。我唯一的问题是实现暂停和恢复方法。由于我对多线程的知识有限,我虽然制作了播放MP3的线程等待,声音会停止,为了恢复歌曲,我只需要通知线程。这是我得到的:

import java.util.Scanner;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

import javazoom.jl.player.Player;

public class MP3 extends Thread{
    private String filename;
    private Player player; 
    private Thread t;
    private volatile boolean continuePlaying = true;

    // constructor that takes the name of an MP3 file
    public MP3(String filename) {
        this.filename = filename;
    }

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        }

        catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

    }

    public void run() {
        play();

            try { 
                while (true) { 
                    synchronized(this) {
                    while(!continuePlaying)
                        wait();


                    player.play();
                    }

                }
            }
            catch (Exception e) { 
                System.out.println(e);

        }

    }



    private void pause() throws InterruptedException{

            System.out.println("Pause");
            continuePlaying = false;



    }

    private void resumeSong() throws InterruptedException{
        synchronized(this) {
            System.out.println("Resume");
            continuePlaying = true;
            notify();

        }
    }

    // test client
    public static void main(String[] args) throws InterruptedException{
        String filename = ("Fall To Pieces.mp3");
        MP3 mp3 = new MP3(filename);
        mp3.start();

        Scanner s = new Scanner(System.in);
        s.nextLine();

        mp3.pause();

        s.nextLine();

        mp3.resumeSong();


        try {
        mp3.join();
    } catch (Exception e){
    }
    }

}

然而,由于某种原因,wait()没有做任何事情,程序甚至没有达到notify()。为什么会这样?

我已经阅读了之前有关此问题的SO问题,但我无法让它们发挥作用。我也有兴趣了解为什么这段代码不起作用,所以我可以进一步理解多线程。谢谢!

1 个答案:

答案 0 :(得分:0)

现在已经很晚了,如果我错误地读了你的代码,请原谅我。但据我所知,你用continuePlaying = true;启动你的线程,run方法只调用play();没有初始化新玩家然后直接进入while (true)循环必须退出点。 continuePlaying不能被那个仍然停留在它的无限循环中的线程改变,即使你启动另一个MP3线程来访问volatile变量,它也会在能够改变任何东西之前进入同一个循环。因此永远不会达到wait()。 稍后,您试图从内部通知()您的等待线程。这有点矛盾,因为它等待被通知并处于等待无所事事的状态,更不用说通知自己了。在通知之前,它根本无法做任何事情,包括通知自己或他人。我想说的是,你应该处理wait(),尤其是来自正在被压缩/等待的线程外部的notify()。

此外,您的player.play();处于奇怪位置。此时播放器应该仅在线程暂停(等待)至少一次之后才开始播放,因为它位于while(!continuePlaying)条件之后。

因此,对于您的情况,我会使用不同线程(甚至是测试的主线程)中的方法来调用wait()和notify()并在相关线程上进行同步。