2010-09-24 50 views
2

我想實現一個帶PipedInputStream的線程化循環緩衝區& PipedOutputStream,但是當我到達解碼器可運行的mHead.write時,它每次都會鎖定。我認爲使用單獨的線程時沒有發生死鎖的機會。爲什麼我的PipedOutputStream死鎖?

private class DecoderTask implements Runnable{ 

    @Override 
    public void run() { 
     while(!mStop){ 
      try { 
        Log.d(TAG,"trying to write"); 
     mHead.write(decode(0, 1000)); 
      mHead.flush(); 
      Log.d(TAG,"Decoded"); 
      } catch (DecoderException e) { 
       Log.e(TAG,e.toString()); 
      } catch (IOException e) { 
       Log.e(TAG,e.toString()); 
      } 
     } 
    } 

} 
private class WriteTask implements Runnable{ 

    @Override 
    public void run() { 
     while(!mStop){ 
      try { 
           Log.d(TAG,"trying to read"); 
       int read = mTail.read(mByteSlave, 0, mByteSlave.length); 
       mAudioTrack.flush(); 
           mAudioTrack.write(mByteSlave,0,read); 
           Log.d(TAG,"read");     
      } catch (IOException e) { 
       Log.e(TAG,e.toString()); 
      } 
     } 
    } 

} 


//in some function 
mTail = new PipedInputStream(); 
mHead = new PipedOutputStream(mTail); 
mByteSlave = new byte[BUF]; 
mT1 = new Thread(new DecoderTask(), "Reader"); 
mT2 = new Thread(new WriteTask(), "Writer"); 
mT1.start(); 
mT2.start(); 
return; 

編輯:這裏是我的服務的完整源http://pastie.org/1179792

logcat的打印輸出:

試圖讀取
試圖寫

回答

0

程序不阻止,它的速度非常慢並且效率低下。它使用100%的CPU。問題是if (mTail.available() >= mByteSlave.length) - 在大多數情況下這將返回false,所以你在這個線程中得到一個繁忙的循環。如果你能擺脫這一點,那就去做吧。然後這個問題就解決了。如果你不能,它會變得更加複雜...

還有一個問題:PipedInputStream.read返回一個int。您需要使用:

int len = mTail.read(mByteSlave, 0, mByteSlave.length); 
mAudioTrack.write(mByteSlave, 0, len); 

除此之外,我在代碼中找不到任何錯誤。我的完整測試用例如下所示:

import java.io.*; 
public class Test2 { 
    PipedOutputStream mHead; 
    PipedInputStream mTail; 
    byte[] mByteSlave = new byte[1024]; 
    boolean mStop; 
    public static void main(String... ar) throws Exception { 
     new Test2().run(); 
    } 
    void run() throws Exception { 
     mTail = new PipedInputStream(); 
     mHead = new PipedOutputStream(mTail); 
     Thread mT1 = new Thread(new DecoderTask(), "Reader"); 
     Thread mT2 = new Thread(new WriteTask(), "Writer"); 
     mT1.start(); 
     mT2.start(); 
    } 
    class DecoderTask implements Runnable { 
     public void run() { 
      while (!mStop) { 
       try { 
        mHead.write(new byte[3000]); 
        mHead.flush(); 
        System.out.println("decoded 3000"); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
    class WriteTask implements Runnable { 
     public void run() { 
      while (!mStop) { 
       try { 
        int len = mTail.read(mByteSlave, 0, mByteSlave.length); 
        if (len < 0) break; // EOF 
        // mAudioTrack.write(mByteSlave, 0, len); 
        // mAudioTrack.flush(); 
        System.out.println("written " + len); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+0

還沒工作,我上面的編輯我的代碼,以反映我現在,日誌輸出說道:試圖寫試圖讀取,然後什麼都沒有,其阻塞讀和寫。 – schwiz 2010-09-24 19:28:57

+0

問題是你指出,以及寫(字節[])沒有定義PipedOutputStream所以它不工作,你必須使用(字節[],int,int)一個 – schwiz 2010-09-24 20:47:12

+0

這不工作像我認爲它確實如此,一旦我從mTail讀取數據後,如何清除數據,它會一遍又一遍讀取相同的數據。 – schwiz 2010-09-24 21:17:46

0

只是擺脫了涉及available()的測試。無論如何,讀取都會被阻止,並且在沒有數據時你沒有更好的辦法。