Ответ 1
Это потому, что чтение System.in(InputStream) - это операция блокировки.
Посмотрите здесь Можно ли читать из InputStream с таймаутом?
У меня есть поток, который выполняет следующий код:
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
не работают.
Это потому, что чтение System.in(InputStream) - это операция блокировки.
Посмотрите здесь Можно ли читать из InputStream с таймаутом?
Вы наткнулись на 9-летнюю bug, которую никто не хочет исправлять. Говорят, что в этот отчет об ошибках есть некоторые обходные пути. Скорее всего, вам нужно будет найти другой способ установки таймаута (ожидание ожидания кажется неизбежным).
Вы можете использовать метод available() (который не блокирует), чтобы проверить, есть ли что-нибудь, что нужно прочитать заранее.
В псевдо-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...
У меня была такая же проблема сегодня, и именно так я ее исправил, используя 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
}
}
}
}
Безопасно ли закрывать поток в другом потоке?
Меня устраивает. В этом случае in.read(...)
генерирует исключение SocketException
.
Если вы хотите дать пользователю некоторое время для ввода данных - возможно, чтобы переопределить значения по умолчанию или прервать некоторый автоматизированный процесс, - тогда подождите сначала и проверьте доступный ввод после паузы:
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*/ }
для этого можно использовать внешний флаг
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);
}
}