为什么我的 PipedOutputStream 死锁?
我正在尝试使用 PipedInputStream & 实现线程循环缓冲区PipedOutputStream 但每次当我到达解码器可运行中的 mHead.write 时它都会锁定。我认为使用单独的线程时不会出现死锁。
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 打印出来:
尝试阅读
试图写
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我遇到了同样的问题,并通过覆盖默认的 PIPE_SIZE ">PipedInputStream(int) 构造函数。该方法 PipedOutputStream.write(byte[], int, int) 会阻塞,直到所有字节都写入输出流。这可能是默认 PIPE_SIZE 的问题。
毕竟,尺寸确实很重要;-)
I have experienced the same problem and resolved it by overriding the default PIPE_SIZE in the PipedInputStream(int) constructor. The method PipedOutputStream.write(byte[], int, int) blocks until all the bytes are written to the output stream. This might be a problem with the default PIPE_SIZE.
After all, size does matter ;-)
该程序不会阻塞,只是非常非常慢且效率低下。它使用 100% CPU。问题是 if (mTail.available() >= mByteSlave.length) - 在大多数情况下这将返回 false,因此您会在该线程中遇到繁忙的循环。如果你能摆脱这个,那就去做吧。那么这个问题就解决了。如果不能,事情会变得更加复杂...
还有另一个问题:
PipedInputStream.read
返回一个 int。您需要使用:除此之外,我在这段代码中找不到任何错误。我的完整测试用例如下所示:
The program doesn't block, it's just very very slow and inefficient. It uses 100% CPU. The problem is
if (mTail.available() >= mByteSlave.length)
- this will return false in most cases, and so you get a busy loop in this thread. If you can get rid of this, do it. Then this problem is solved. If you can't, it gets more complicated...There is another problem:
PipedInputStream.read
returns an int. You need to use:Other than that, I couldn't find anything wrong in this code. My complete test case looks like this:
只需摆脱涉及 available() 的测试即可。无论如何,读取都会阻塞,当没有数据时你没有什么更好的事情可做。
Just get rid of the test involving available(). The read will block anyway, and you have nothing better to do when there is no data.