我正在尝试编写一个下载视频直播流的算法。具体来说,我试图获取的相应流基于动态 .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
答案 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();
}
}