2014-12-04 3 views
4

두 개의 다른 소스에서 입력을받는 다중 스레드 콘솔 앱이 있습니다. 하나는 콘솔에 입력하는 사용자이고 다른 하나는 네트워크입니다. 나는 BufferedReader.readline()을 사용하여 사용자와 그 블럭으로부터 입력을 얻는다. 기다리고있는 동안 네트워크 입력을받지 않는다면 좋다. 이 경우 readline()을 취소하여 사용자 스레드의 차단을 해제해야합니다.Java에서 System.in을 닫은 후 System.in을 다시 열 수 있습니다.

취소하는 가장 좋은 방법은 System.in을 닫고 readline()이 예외를 throw하는 것입니다. 그 후에는 다시 열어야합니다. 그게 가능하니?

+0

에 약간의 사용이다. – Secondo

+0

[System.in'을 열지 않았으므로 결코 닫아서는 안됩니다.] (http://stackoverflow.com/a/7457737/545127). – Raedwald

답변

7

System.in, System.out 또는 System.err을 다시 열 수 없습니다. 기본 네이티브 스트림은 다른 프로세스 또는 응용 프로그램이 식별 할 수없는 ID를 가진 파일에 연결된 파일 설명자입니다. 기본 네이티브 파일 기술자가 닫히면 다시 열 수 없습니다.

내가 제안 할 수있는 가장 좋은 방법은 System.in 개체의 래퍼 InputStream을 만들고 래퍼를 코딩하여 close()을 no-op로 처리하는 것입니다. 또는 래퍼 스트림을 실제로 닫지 않고 래퍼를 "닫힌"상태로 설정할 수도 있습니다.

System.in에서 읽는 동안 차단 된 스레드의 차단을 "해제"해야하므로 특정 사용 사례에서는 작동하지 않습니다. 따라서 귀하의 경우에는 System.in에서 비 차단 입력을해야합니다. 예를 들어 available() 메서드를 사용하여 콘솔에서 읽을 문자가 있는지 테스트합니다. 일반적으로 available()이 0보다 큰 숫자를 반환하면 전체 행을 읽을 수 있다고 가정하는 것이 안전합니다.

(Selector을 사용하여 비 차단 읽기를 구현할 수도 있지만 'T는 System.in 개체에 대한 "선택 채널"을 얻을 수 있다고 생각합니다.) Thread.interrupt()가 작동하지 않습니다


참고. javadocs에 따르면, 인터럽트 가능 채널에서 읽는 경우에만 작동합니다.

  • System.in는 인터럽트 채널없고,

  • 가 되었다면, interrupt() 대한 기록 동작은, 채널이 인터럽트에 의해 폐쇄 도착이다.

+0

하지만 user1379635는 close()를 사용하여 스레드를 인터럽트하려고했습니다.no-op로는이를 구현하지 않으므로 close()를 호출 할 필요가 없습니다. 래퍼를 "닫힌"상태로 설정하면 블록 스레드가 중단되지 않습니다. – slipperyseal

+0

답변 해 주셔서 감사합니다. 내가 다시 디자인해야 할 것 같아. – ForeverNoobie

1

나는이 문제가 자바 자체에 의해 타격을 입지 않는다는 것을 이상하게 여겼다. 뭔가 빠져 있지 않은가?

어쨌든, 여기에 스티븐 C, 그리고 덕분에 익명 클래스와 자신의 아이디어를 사용하기위한 작은 예입니다 (인라인, system.in을위한 스캐너를 만들 때)

(그래서, 대신의 InputStream의 FilterInputStream를 사용 내가

희망) 생성자에 System.in를 전달할 수 있다는이 내가 그 노 생각하면

public class MultiopenScanner { 
    public static int scanInt() throws IOException{ 
     //Scanner sc = new Scanner(System.in); 
     Scanner sc = new Scanner(new FilterInputStream(System.in){public void close(){}}); 
     int res = sc.nextInt(); 
     sc.close(); 
     return res; 
    } 

    public static void main(String[] args) throws IOException { 
     int i=1; 
     while (i>0) { 
      System.out.println("Give me an int please : "); 
      //some might need this : System.out.flush(); 
      i = scanInt(); 
      System.out.println("got "+i); 
     } 
     System.out.println("done"); 
    } 
} 
관련 문제