разбудить поток из readLine() (из System.in, без сокета)

У меня есть 2 потока: main и Thread2.

Главное --> создать Thread2, приостановить работу на 3 секунды, выйти.

Thread2 --> прочитать строку из System.in и выйти.

Я хочу разбудить Thread2, если он заблокирован в readline(), я не хочу использовать тайм-аут, и закрытие основного потока ввода путем создания исключения в Thread2 не работает.

Код:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;

public class Main {    
  public static void main(String[] args) throws InterruptedException {
    InputStreamReader sc = new InputStreamReader(System.in);

    Thread2 t = new Thread2(sc);
    Thread tt = new Thread(t);
    tt.start();

    Thread.sleep(3000);
    System.out.println("exit sleep");

    tt.interrupt();
    System.out.println("exit main");
  }
}

class Thread2 implements Runnable {
  InputStreamReader qst;

  public Thread2(InputStreamReader sc) {
    qst = sc;
  }  
  public void run() {
    BufferedReader buff = new BufferedReader(qst);
    try {
      System.out.println("read thread");

      buff.readLine(); //Here is locked!!!!!!!!!!!!!!!!!!
    } catch (InterruptedIOException e) {
      System.out.println("exit thread");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Выполнение (println):

-Читать ветку

(через 3 секунды)

-выйти из сна

-выход из главного

Но Thread2 без остановки -> это блок в строке чтения. Почему?


person John    schedule 25.07.2016    source источник


Ответы (2)


Вы можете установить свой поток на демона:

tt.setDaemon(true);

Док говорит:

Помечает этот поток либо как поток демона, либо как пользовательский поток. Виртуальная машина Java завершает работу, когда единственными запущенными потоками являются все потоки демона.

В вашем случае tt перестанет работать, когда закончится основной поток.

person TMichelsen    schedule 25.07.2016

Здесь есть два варианта:

  1. Как предлагали другие, вам как-то нужно принудительно закрыть входной поток
  2. Вы можете сделать шаг назад и подумать о том, чтобы перепроектировать все: Java предлагает методы для неблокирующего ввода-вывода. Вы можете обратиться здесь для получения некоторых первых рекомендаций. как это сделать.

Конечно, это действительно зависит от вашего контекста, какой из двух имеет больше смысла. Вариант 2, конечно, означает совсем другой подход; но с другой стороны: если вы не хотите блокировать чтение, тогда хорошо: вы не должны блокировать чтение.

person GhostCat    schedule 25.07.2016
comment
спасибо за 2 пункта ответов, 1 пункт не работает, может быть потому, что inputstrem неблокирует, верно? - person John; 25.07.2016
comment
@John Для System.in нет неблокирующего ввода-вывода. - person user207421; 17.08.2017