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