所以,如果我已经正确地理解了这一点,当我们在一个对象上调用wait时它会进入等待状态,并且当它等待对象的锁定时它会进入阻塞状态(比如当试图进入同步时)块或方法)。
像read()这样的I / O方法如何将线程置于阻塞状态?我理解为什么它必须处于阻塞状态,等待它可以读取的数据,但我也对HOW感兴趣。当JVM尝试读取的资源中的数据再次可用时,JVM如何通知线程它可以继续?
答案 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
,调用read
。 RESTARTABLE
宏会在出现错误时循环,errno
为EINTR
。
在Windows中,IO_Read
定义为handleRead
,调用ReadFile
。