我正在http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html查看来自Apache Commons的IOUtils.copy()
的实现,最终归结为:
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
// DEFAULT_BUFFER_SIZE is 4096
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
我在Executor
中运行此任务,该任务有超时等但如果我理解正确,即使它超时并取消Future
,该线程仍会继续运行,因为有在此循环中的任何位置都不检查线程状态。这会导致危险的泄漏和饥饿。
似乎我需要重写循环,但处理这个问题的理智和正确方法是什么? throw new IOException(new InterruptedException())
?将方法声明为抛出InterruptedException
并抛出它(讨厌为我的所有IO辅助方法执行此操作)?
编辑 :我刚从Guava检查ByteStreams
,他们似乎在做同样的事情。现在我想知道为什么两个主要的库不支持这种循环中的中断。我错过了什么吗?
答案 0 :(得分:1)
如果您关闭input
和/或output
,copyLarge
方法将抛出异常,退出循环。
答案 1 :(得分:1)
对于任何阻塞I / O(即java.io包),您必须手动检查并执行某些操作以响应它。
if (Thread.currentThread().isInterrupted()) {
// do something here to stop processing
}
如果您正在使用频道(java.nio),则不必执行此操作。在其中一个NIO操作期间发出的任何线程中断都会导致该操作抛出ClosedByInterruptException。