如何停止在 Java 中阻塞读取操作中等待的线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4182491/
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
How to stop a thread waiting in a blocking read operation in Java?
提问by vitaut
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.
哪里in
是System.in
。我怎样才能优雅地停止这样的线程?关闭System.in
和使用Thread.interrupt
似乎都不起作用。
采纳答案by PeterMmm
This is because reading System.in (InputStream) is a blocking operation.
这是因为读取 System.in (InputStream) 是一个阻塞操作。
Look here Is it possible to read from a InputStream with a timeout?
回答by Paolo
You could use the available() method (which is non-blocking) to check whether there is anything to read beforehand.
您可以使用 available() 方法(它是非阻塞的)来检查是否有任何要事先阅读的内容。
In pseudo-java:
在伪Java中:
//...
while(running)
{
if(in.available() > 0)
{
n = in.read(buffer);
//do stuff with the buffer
}
else
{
Thread.sleep(500);
}
}
//when running set to false exit gracefully here...
回答by asela38
you can use a external flag for this
您可以为此使用外部标志
boolean flag = true;
public void run() {
try {
int n = 0;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1 && flag) {
out.write(buffer, 0, n);
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
回答by Andreas Dolk
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:
如果你想给用户一些时间来输入数据——也许是为了允许覆盖默认值或中断一些自动化过程——然后先等待并在暂停后检查可用的输入:
System.out.println("Enter value+ENTER within 5 Seconds to override default value: ");
try{
Thread.sleep(5000);
} catch {InterruptedException e){}
try{
int bytes = System.in.available();
if (bytes > 0) {
System.out.println("Using user entered data ("+size+" bytes)");
} else {
System.out.println("Using default value");
}
} catch(IOException e) { /*handle*/ }
回答by Denis Tulskiy
You've stumbled upon a 9 year old bugno 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).
您偶然发现了一个存在 9 年的错误,没人愿意修复。他们说在这个错误报告中有一些解决方法。很可能,您需要找到其他方法来设置超时(忙等待似乎不可避免)。
回答by Nans
I had the same problem today, and this is how I fixed it, using in.ready()
:
我今天遇到了同样的问题,这就是我修复它的方法,使用in.ready()
:
public void run() {
String line;
// Some code
while(!Thread.currentThread().isInterrupted()){
try {
if (in.ready()) {
line = in.readLine();
}
} catch (Exception e) {
try {
Thread.currentThread().wait(500);
} catch (InterruptedException e1) {
// Do what we want when thread is interrupted
}
}
}
}
回答by tdx
Is it safe to close in stream in other thread?
It works for me. In this case, in.read(...)
throws exception SocketException
.
在其他线程中关闭流是否安全?这个对我有用。在这种情况下,in.read(...)
抛出异常SocketException
。