2013-07-19 169 views
1

我刚开始使用Jlayer库播放MP3。它完美的工作,我可以播放歌曲。我唯一的问题是实现暂停和恢复方法。由于我对多线程的知识有限,所以我通过制作线程来播放MP3等待,声音将停止,为了恢复歌曲,我只需要通知该线程。以下是我的了:JLayer暂停和恢复

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){ 
    } 
    } 

} 

出于某种原因,然而,等待()什么都不做,程序甚至没有达到通知()。这是为什么发生?

我读过以前的关于这个问题的SO问题,但我一直无法让它们工作。我也有兴趣了解为什么这段代码不工作,所以我可以进一步理解多线程。谢谢!

+0

解决方案是在这里:http://stackoverflow.com/questions/12057214/jlayer-pause-and-resume-song – pi4630

回答

0

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

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

因此,对于你的情况我会与评价者在不同的线程(甚至为你测试的主线程),它调用一个wait()和notify()上,并在对有关​​线程同步的方法去。

+0

哦,我明白了。这是我第一次使用线程,所以我想你是对的。但是,我的问题是我怎样才能保持线程活着没有使用while循环?另外,如果我永远不能改变布尔值,我该如何暂时挂起线程? – amb110395

+1

@ amb110395为什么要根据线程中的变量暂停线程?有什么反对调用mp3.wait();而不是mp3.pause()和相同的通知(保持同步在那些中)?更进一步,你不需要一个永久循环来保持你的线程活着。像任何其他对象,它应该没问题,只要它有一个活动的引用,它作为变量mp3 .. – Akunosh

+0

是的,我做了类似的,它的工作。无论如何,谢谢你 – amb110395