没有抛出ClosedByInterruptException

Ger*_*ler 5 java io multithreading exception

JDK文档说,如果当前在InterruptibleChannel的io操作中阻塞的线程被中断,则通道将关闭,并引发ClosedByInterruptException。但是,使用FileChannel时出现不同的行为:

public class Main implements Runnable {

public static void main(String[] args) throws Exception {
    Thread thread = new Thread(new Main());
    thread.start();
    Thread.sleep(500);
    thread.interrupt();
    thread.join();
}

public void run() {
    try {
        readFile();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

private void readFile() throws IOException {
    FileInputStream in = new FileInputStream("large_file");
    FileChannel channel = in.getChannel();
    ByteBuffer buffer = ByteBuffer.allocate(0x10000);
    for (;;) {
        buffer.clear();
        // Thread.currentThread().interrupt();
        int r = channel.read(buffer);
        if (Thread.currentThread().isInterrupted()) {
            System.out.println("thread interrupted");
            if (!channel.isOpen())
                System.out.println("channel closed");
        }
        if (r < 0)
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

在此,当线程中断时,即使通道已关闭,read()调用也会正常返回。没有异常被抛出。此代码显示“线程中断”和“通道关闭”,然后在下一次调用read()时,抛出ClosedChannelException。

我想知道是否允许这种行为。据我了解的文档,read()应该要么正常返回而不关闭通道,要么关闭通道并抛出ClosedByInterruptException。正常返回并关闭通道似乎不正确。我的应用程序遇到的麻烦是,当执行io的FutureTask被取消时,我在其他地方遇到了意外的,看似无关的ClosedChannelException。

注意:当线程在进入read()时已被中断时,将按预期引发ClosedByInterruptException。

我已经使用64位Server-VM(JDK 1.6.0 u21,Windows 7)看到了此行为。有人可以确认吗?

Ste*_*n C 0

一种可能性是您的程序实际上在中断传递之前到达了文件末尾。当您看到当前线程已被中断时,尝试更改您的程序以计算读取和输出的字节总数。