Java 如何避免缓冲数据流饥饿?

Java 如何避免缓冲数据流饥饿?,java,httpurlconnection,bufferedinputstream,Java,Httpurlconnection,Bufferedinputstream,我通过BufferedInputStream从源位置读取数据,并使用BufferedOutputStream将数据传递到目标位置。我遇到的问题是,由于带宽不足,有时我的线程永远不会退出while循环。有什么想法吗?代码如下: BufferedInputStream bis = new BufferedInputStream(sourceConnection.getInputStream()); BufferedOutputStream request = new BufferedOutputSt

我通过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();

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

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

谢谢你的帮助

你的问题似乎有点不对劲;如果连接保持打开状态,线程将永远不会退出循环。为什么要这样做?如果问题是输出流没有刷新,只需在写入字节后在循环中移动刷新调用即可。目前,我同意杜兰达尔的观点。该循环应该只在断开连接或其他同样不可恢复的事件中退出。我更改的代码仍然不起作用。查看编辑。您的while循环可以收缩为:while length=bis.readinput!=-1{request.writeinput,0,长度;request.flush;}
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();