簡體   English   中英

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

[英]Block I/O in InputStream's read()

我正在嘗試編寫一種算法,可以下載視頻直播流。 具體來說,我要提取的各個流基於動態.m3u8播放列表文件,該文件會定期提供新視頻文件的URI。 主要目標是將這些單獨的媒體文件組合到一個一致的InputStream中。
我實際上成功地使它起作用:我定期檢查播放列表中是否出現了新的媒體文件,並將它們的HTTP流傳遞給自定義的InputStream實現,即InputStreamChain 由於它是實時流,因此至少在目前,我認為它是無止境的 因此,我希望我的InputStreamChainread()永遠不要發送-1。 不幸的是,它確實做到了。 每當所有排隊的媒體流都用完時, InputStreamChain結束。 相反,我希望它阻止I / O,直到出現新的媒體文件。 因此,我想出了一個可行的解決方案:我調整了read()方法使其循環播放,直到有新的流可用為止( TimerTask將提供新文件)。 在循環中,我內置了Thread.sleep() ,以減少CPU負載:

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;
}

盡管它似乎可行,但是我有一種感覺,就是我沒有按照我的預期去做。 我還嘗試將LockCondition.await()一起使用,但是當我的TimerTask嘗試觸發Condition.signal() ,它只是拋出了IllegalMonitorStateException
這就是為什么我問這個問題

我應該以哪種方式延遲/阻止InputStream的read()方法,尤其是在我的場景中?

編輯:

為了完整起見,我還將提供失敗的Lock方法:

private ReentrantLock ioLock;
private Condition ioCond;
private boolean waitingForStream = false;

public InputStreamChain() {
    ioLock = new ReentrantLock();
    ioCond = ioLock.newCondition();
}

public synchronized InputStreamChain addInputStream(final InputStream stream) {
    streams.addLast(stream);
    if (current == null) {
        current = streams.removeFirst();
    }
    if(waitingForStream) {
        ioCond.signal();
    }
    return this;
}

public int read() throws IOException {
    int bit = current.read();
    if (bit == -1 && streams.size() > 0) {
        // do stuff
    } else if(bit == -1) {
        waitingForStream = true;
        ioLock.lock();
        try {
            ioCond.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            waitingForStream = false;
            ioLock.unlock();
        }
        return read();
    }
    return bit;
}

可能您未使用同步塊。 這是一個例子:

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();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM