2013-07-19 219 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