如何避免饿死BufferedInputStream?

时间:2014-10-17 17:43:00

标签: java httpurlconnection bufferedinputstream

我通过BufferedInputStream从源位置读取数据,然后使用BufferedOutputStream将数据传递到目标位置。我遇到的问题是,由于带宽匮乏,有时我的线程永远不会退出while循环。有任何想法吗?这是代码:

BufferedInputStream bis = new BufferedInputStream(sourceConnection.getInputStream());
BufferedOutputStream request = new BufferedOutputStream(destConnection.getOutputStream());
request.write(content.getBytes("UTF-8"));
boolean eof = false;
byte[] input = new byte[4096];
while ((length = bis.read(input)) != -1) {
    request.write(input, 0, length);
    request.flush();
}
request.close();
bis.close();

1 个答案:

答案 0 :(得分:0)

所以为了解决这个问题,我做了一些事情。我使用具有超时的执行程序在单独的线程中设置整个传输过程

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final Future<Boolean> handler = executor.submit(new Callable<Boolean>() {
    @Override
    public Boolean call() throws Exception {
        return processTransfer();
    }
});
success = handler.get(10, TimeUnit.MINUTES);

这样,如果传输时间超过10分钟,它就会以一个例子退出。第二件事是更改原始代码以检测饥饿:

long lastDataRecvTime = System.currentTimeMillis();
byte[] input;
while (true) {
    if(System.currentTimeMillis() - lastDataRecvTime >= 5 * 60 * 1000) {
        throw new RuntimeException("Nothing received for 5 minutes. Transfer starved. Exiting");
    }
    int availableBuf = request.getAvailableBufferSize();
    if(availableBuf == 0) {
        request.flush();
        continue;
    }
    input = new byte[Math.min(4096, availableBuf)];
    int length = bis.read(input);
    if (length == -1)
        break;

    if(length == 0) {
        try { Thread.sleep(1); } catch (Exception ignored){}
        continue;
    }

    lastDataRecvTime = System.currentTimeMillis();
    request.write(input, 0, length);
}
request.flush();
request.close();
bis.close();

感谢您的帮助