Java BufferedReader readline 阻塞?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2776724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java BufferedReader readline blocking?
提问by tgguy
I want to make an HTTP request and then get the response as sketched here:
我想发出一个 HTTP 请求,然后得到这里所描绘的响应:
URLConnection c = new URL("http://foo.com").openConnection();
c.setDoOutput(true);
/* write an http request here using a new OutputStreamWriter(c.getOutputStream) */
BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream));
reader.readLine();
But my question is, if the request I send takes a long time before a response is received, what happens in the call reader.readLine() above? Will this process stay running/runnable on the CPU or will it get taken off the CPU and be notified to wake up and run again when there is IO to be read?
但我的问题是,如果我发送的请求在收到响应之前需要很长时间,那么上面的调用 reader.readLine() 会发生什么?这个进程会在 CPU 上保持运行/可运行,还是会从 CPU 上取下并在有 IO 读取时被通知唤醒并再次运行?
If it stays on the CPU, what can be done to make it get off and be notified later?
如果它停留在 CPU 上,可以做些什么让它下车并稍后得到通知?
回答by jasonmp85
What the others have said is correct. Java's "old I/O" library in java.io contains blocking calls. But they do not busy wait. They are blocking on I/O and the kernel will reschedule them once more I/O is available.
其他人说的都是对的。java.io 中 Java 的“旧 I/O”库包含阻塞调用。但他们不忙等待。它们在 I/O 上阻塞,一旦有更多 I/O 可用,内核将重新调度它们。
I wasn't totally sure, so I tried it out for myself. Take this sample class:
我不是很确定,所以我自己试了一下。拿这个示例类:
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line = reader.readLine();
System.out.println(line);
}
}
And compile it on the command line. Then run it, but don't type anything. The program should be blocking on input until you type a character, and it will not progress past readline until you type enter. psshould be able to tell us more details about this process. Use the aflag to get more detailed information from ps:
并在命令行上编译它。然后运行它,但不要输入任何内容。在您输入字符之前,程序应该阻塞输入,并且在您输入 enter 之前它不会超过 readline。ps应该能够告诉我们有关此过程的更多详细信息。使用该a标志从ps以下位置获取更多详细信息:
japeters@<computer-name>] ps a
PID TT STAT TIME COMMAND
3846 s000 S 0:00.16 -zsh
3992 s000 S+ 0:00.40 /usr/bin/java Test
The man page for PS says:
PS的手册页说:
stateThe state is given by a sequence of characters, for example, ``RWNA''. The first character indicates the run state of the process:
- IMarks a process that is idle (sleeping for longer than about 20 seconds).
- RMarks a runnable process.
- SMarks a process that is sleeping for less than about 20 seconds.
state状态由字符序列给出,例如“RWNA”。第一个字符表示进程的运行状态:
- I标记一个空闲的进程(睡眠时间超过大约 20 秒)。
- R标记一个可运行的进程。
- S标记睡眠时间少于 20 秒的进程。
And since I just started the process, Smakes sense. The process is sleeping, awaiting scheduling by the OS. Indeed, if you check top, you'll notice the process is taking 0% CPU.
因为我刚刚开始这个过程,所以S是有道理的。进程正在休眠,等待操作系统调度。事实上,如果您检查top,您会注意到该进程占用了 0% 的 CPU。
So don't worry about the performance of this call, there's no busy waiting or polling going on: the system is taking care of the I/O events for you and will intelligently handle your process.
所以不要担心这个调用的性能,不会有忙于等待或轮询的情况:系统会为你处理 I/O 事件,并会智能地处理你的进程。
回答by LM.
A good OS will have a scheduler that puts the process into a blocked or similar state, and any task switches will not switch to the blocked process.
一个好的操作系统会有一个调度程序,将进程置于阻塞或类似状态,任何任务切换都不会切换到阻塞进程。
For example, The idle process in windows is what runs when there are no processes ready to run (sleeping, blocked, etc.).
例如,Windows 中的空闲进程是在没有准备运行的进程(休眠、阻塞等)时运行的进程。

