我刚刚开始使用Jlayer库来玩MP3s。它工作得很好,我可以播放这首歌。我唯一的问题是实现pause和resume方法。以我有限的多线程知识,我认为让我播放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问题,但我还没能让它们工作。我也有兴趣了解为什么这段代码不能工作,这样我就可以进一步理解多线程。谢谢!
发布于 2013-07-20 07:18:49
这里很晚了,如果我读错了你的代码,请原谅。但据我所知,你用continuePlaying = true;启动你的线程,run方法只是调用play(); no初始化新播放器,然后直接进入一个必须退出的while (true)循环。仍然停留在无限循环中的线程不能更改continuePlaying,即使您启动另一个MP3线程来访问易失性变量,它也会进入相同的循环,然后才能进行任何更改。因此,wait()永远不会到达。稍后,您将尝试从线程内部通知()等待的线程。这有点自相矛盾,因为它在等待通知,处于等待状态,什么也不做,更不用说通知自己了。除非得到通知,否则它不能做任何事情,包括通知自己或通知其他人。我想说的是,您应该处理wait(),但特别是从正被寻址/等待的线程外部处理notify()。
此外,你的player.play();处于一个奇怪的位置。目前,播放器应该只在线程暂停(等待)至少一次之后才开始播放,因为它处于while(!continuePlaying)条件之后。
因此,对于您的情况,我会使用不同线程(甚至是测试的主线程)中的方法进行评分,这些线程在相关线程上调用wait()和notify(),并在该线程上同步。
https://stackoverflow.com/questions/17756516
复制相似问题