1

我刚开始使用 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 问题,但我无法使它们起作用。我也有兴趣了解为什么这段代码不起作用,以便进一步了解多线程。谢谢!

4

1 回答 1

0

来晚了,如果我读错了你的代码,请原谅我。但据我所见,你开始你的线程,continuePlaying = true;运行方法只是调用play();no 初始化新播放器,然后直接进入一个while (true)循环至极必须退出点。continuePlaying 不能被仍然卡在无限循环中的线程更改,即使您启动另一个 MP3 线程来访问 volatile 变量,它也会在能够更改任何内容之前进入相同的循环。因此永远不会到达 wait() 。稍后,您尝试从内部通知()您的等待线程。这有点自相矛盾,因为它正在等待被通知并且处于等待什么都不做的状态,更不用说通知自己了。在收到通知之前,它根本无法做任何事情,包括通知自己或其他人。我想说的是,您应该处理 wait() 但特别是从正在处理/等待的线程外部处理 notify()。

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

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

于 2013-07-19T23:18:48.710 回答