2010-09-24 127 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()的测试。无论如何,读取都会被阻止,并且在没有数据时你没有更好的办法。