在InputStream的read()中阻止I / O

时间:2013-05-31 11:49:11

标签: java multithreading concurrency io inputstream

我正在尝试编写一个下载视频直播流的算法。具体来说,我试图获取的相应流基于动态 .m3u8 播放列表文件,该文件周期性地提供新视频文件的URI。主要目标是将这些单独的媒体文件组合成一个连贯的InputStream 我实际上成功地使其工作:我定期检查播放列表中出现的新媒体文件,并将其HTTP流传递给自定义的InputStream实现,即InputStreamChain。由于它是一个实时流,我认为它是无尽的,至少目前是这样。因此,我希望InputStreamChain的{​​{1}}永远不会发送-1。不幸的是,它做到了;每次消耗所有排队的媒体流时,read()结束。相反,我希望它阻止I / O,直到新的媒体文件到达。 所以,我提出了一个有效的解决方案:我调整了InputStreamChain方法以循环,直到有新的流可用(read()将提供新文件)。在循环中,我内置了TimerTask,以减少CPU负载:

Thread.sleep()

虽然它似乎有用,但我有一种感觉,我不应该这样做。我还尝试将public int read() throws IOException { int bit = current.read(); if (bit == -1 && streams.size() > 0) { // left out due to lacking relevance } else if(bit == -1 && streams.size() == 0) { while(streams.size() == 0) { Thread.currentThread().sleep(50); } return read(); } return bit; } Lock一起使用,但当我的Condition.await()尝试触发TimerTask时,它只是扔了一个Condition.signal()。 这就是为什么我问问题

我应该以什么方式延迟/阻止InputStream的IllegalMonitorStateException方法,特别是在我的场景中?

修改

为了完整起见,我也将提供失败的read()方法:

Lock

1 个答案:

答案 0 :(得分:1)

可能你没有使用synchronized块。这是一个例子:

class MyReader
{
     public int read() throws IOException {  
        int bit = current.read();  
        if (bit == -1 && streams.size() > 0) {  
            // left out due to lacking relevance
        } else if(bit == -1 && streams.size() == 0) {
            waitForNextStream();
            return read();
        }
        return bit;
    }

    private synchronized void waitForNextStream()
    {
        // TODO add close handling, set current here
        while (streams.isEmpty())
        {
            wait();
        }
    }


    public synchronized void addNextStream(InputStream is)
    {
        streams.add(is);
        notify();
    }
}