如何停止在 Java 中等待阻塞读操作的线程?
我有一个执行以下代码的线程:
public void run() {
try {
int n = 0;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
其中 in
是 System.in
。我怎样才能优雅地停止这样的线程?关闭 System.in 和使用 Thread.interrupt 似乎都不起作用。
I have a thread that executes the following code:
public void run() {
try {
int n = 0;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
where in
is System.in
. How can I stop such thread gracefully? Neither closing System.in
, nor using Thread.interrupt
appear to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这是因为读取 System.in (InputStream) 是一个阻塞操作。
看看这里 是吗可以从输入流中读取超时吗?
This is because reading System.in (InputStream) is a blocking operation.
Look here Is it possible to read from a InputStream with a timeout?
您偶然发现了一个 9 年前的bug,没有人愿意修复。他们说此错误报告中有一些解决方法。最有可能的是,您需要找到其他方法来设置超时(忙碌等待似乎是不可避免的)。
You've stumbled upon a 9 year old bug no one is willing to fix. They say there are some workarounds in this bug report. Most probably, you'll need to find some other way to set timeout (busy waiting seems unavoidable).
您可以使用 available() 方法(非阻塞)来检查是否有任何内容可以预先读取。
在伪java中:
You could use the available() method (which is non-blocking) to check whether there is anything to read beforehand.
In pseudo-java:
在其他线程中关闭流是否安全?
这对我有用。在这种情况下,
in.read(...)
抛出异常SocketException
。Is it safe to close in stream in other thread?
It works for me. In this case,
in.read(...)
throws exceptionSocketException
.如果您想给用户一些时间来输入数据(可能是为了允许覆盖默认值或中断某些自动化过程),那么首先等待并在暂停后检查可用的输入:
If you want to give a user some time to enter data - maybe to allow overriding default values or interrupting some automated process -, then wait first and check available input after the pause:
我今天遇到了同样的问题,这就是我使用
in.ready()
修复它的方法:I had the same problem today, and this is how I fixed it, using
in.ready()
:您可以为此使用外部标志
you can use a external flag for this