像read()这样的I / O方法如何在java中将Thread置于阻塞状态?

时间:2016-12-14 11:48:05

标签: java multithreading blocked blocked-threads

所以,如果我已经正确地理解了这一点,当我们在一个对象上调用wait时它会进入等待状态,并且当它等待对象的锁定时它会进入阻塞状态(比如当试图进入同步时)块或方法)。

像read()这样的I / O方法如何将线程置于阻塞状态?我理解为什么它必须处于阻塞状态,等待它可以读取的数据,但我也对HOW感兴趣。当JVM尝试读取的资源中的数据再次可用时,JVM如何通知线程它可以继续?

2 个答案:

答案 0 :(得分:4)

它不会将线程的状态更改为BLOCKED

public static void main(String[] args) throws IOException {
    Thread main = Thread.currentThread();
    new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            System.out.println(main + " is in "+main.getState()+" state");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new AssertionError(e);
            }
        }
    }).start();
    System.in.read();
}

打印

Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
Thread[main,5,main] is in RUNNABLE state
相反,操作系统不会从read返回,直到有一些数据,操作系统决定是否以及何时上下文切换线程/进程。

  

当JVM尝试读取的资源中的数据再次可用时,JVM如何通知线程它可以继续?

当有更多数据或流已关闭时,操作系统会唤醒线程。 JVM没有参与其中。

答案 1 :(得分:0)

这取决于原生平台。

在POSIX中,对read的调用通常会阻塞,直到数据可用,但还有许多其他原因需要返回,例如到达文件结尾,文件描述符已关闭,操作定时out或信号中断了操作。

在Windows中,最密切相关的功能是ReadFile

gory详细信息,请参阅Java 8更新112 b15:

FileInputStream.read调用原生FileInputStream.read0,通过Java_java_io_FileInputStream_read0中的JNI本地实现,调用readSingle,调用IO_Read

在POSIX中,IO_Read定义为handleRead,调用readRESTARTABLE宏会在出现错误时循环,errnoEINTR

在Windows中,IO_Read定义为handleRead,调用ReadFile