2011-02-13 2 views
5

다중 스레드 환경을 사용하고 있습니다. 하나의 스레드가 반복적으로 scanner.nextLine()을 호출하여 사용자 입력을 계속 수신합니다. 응용 프로그램을 종료하려면이 실행 루프가 다른 스레드에 의해 중지되지만 청취 스레드는 마지막 사용자 입력이 이루어질 때까지 중지되지 않습니다 (차단 특성이 nextLine()이므로).java.util.Scanner nextLine 호출을 인터럽트하는 방법

닫을 수없는 InputStream을 반환하는 System.in에서 읽기 때문에 스트림 닫기가 옵션으로 보이지 않습니다.

스캐너의 차단을 방해하여 반환 할 수있는 방법이 있습니까?

감사

+0

당신은'scanner.nextLine()'대신'scanner.hasNext()'를 호출 할 수 있습니다.이 메소드는 javadoc에 따라 차단 될 수도 있습니다. 따라서 처리해야 할 수도 있습니다. 'scanner.nextLine()'과 달리'scanner.hasNext()'는 입력을 진행하지 않기 때문에'scanner.nextLine()을 호출하기 전에 읽기 스레드가 다른 스레드에 의해 중단 되었다면 플래그를 검사 할 수 있습니다.)' –

+1

네,하지만 이것은 지속적인 폴링을 포함합니다. –

+0

청취 스레드에서 Thread.interrupt를 호출 할 수 있어야합니다. 이로 인해 ioException() 메소드에서 얻을 수있는 InterruptedIOException이 발생할 수 있습니다. nextLine()과 상호 작용하는 방법이나 기본 입력 스트림과 작동하는 방법을 잘 모르지만 대부분의 경우 nextLine을 종료해야합니다. – josefx

답변

8

article은 읽을 때 차단 방지에 대한 접근 방법을 설명합니다. 그것은 코드 스 니펫 (snippet)을 주며, 주석에 표시 할 때 수정할 수 있습니다.

import java.io.*; 
import java.util.concurrent.Callable; 

public class ConsoleInputReadTask implements Callable<String> { 
    public String call() throws IOException { 
    BufferedReader br = new BufferedReader(
     new InputStreamReader(System.in)); 
    System.out.println("ConsoleInputReadTask run() called."); 
    String input; 
    do { 
     System.out.println("Please type something: "); 
     try { 
     // wait until we have data to complete a readLine() 
     while (!br.ready() /* ADD SHUTDOWN CHECK HERE */) { 
      Thread.sleep(200); 
     } 
     input = br.readLine(); 
     } catch (InterruptedException e) { 
     System.out.println("ConsoleInputReadTask() cancelled"); 
     return null; 
     } 
    } while ("".equals(input)); 
    System.out.println("Thank You for providing input!"); 
    return input; 
    } 
} 

이 코드를 직접 사용하거나 새로운 closable InputStream 클래스를 작성하여이 기사에서 설명한 논리를 래핑 할 수 있습니다.

+2

안녕하세요, 저는 적극적인 대기를 포함하지 않는 솔루션을 기대했습니다. –

0

확실히. 핵무기를 사용하십시오. 주 스레드 끝에 System.exit(0)으로 전화하십시오. 이것은 모든 것을 죽일 것이다. System.in에서 대기중인 활성 스레드조차.

문제는 System.in이 차단 기능이있는 기존의 입력 스트림이고 스레드가 차단되면 스레드가 실행 중으로 표시된다는 것입니다. 당신은 그것을 방해 할 수 없습니다. 따라서 System.in을 읽는 데 사용하는 스레드가 무엇이든간에 read를 호출하면 스레드가 스레드를 차단합니다. 당신은 블록을 없애고 끊임없이 설문 조사를 할 수있는 경우를 제외하고는 읽기를 부르는 것을 피하기 위해 여러 가지 기법을 동축시킬 수 있습니다. 그러나이 문제를 해결하기위한 시도는 스레드를 잠그고 기본 스트림을 닫지 않거나 스레드를 중단하거나 중지하지 않으면 문제를 해결할 수 없습니다. 하지만 VM 전체를 죽이면 실이 죽을거야

분명히 나머지 스레드가 제대로 종료되었는지 확인해야합니다. 마지막으로 행인을 입력하는 입력 된 스레드에 응답 할 수 있기를 바보 인 것입니다. 그러나 이것이 완전히 맞는 경우, 정답은 아무런 이유없이 클럭 사이클을 일으키지 않고 프로그램을 종료하게하는 유일한 답입니다.

+2

나는 이것을 실제로 시험해 보았고,'System.exit (0)'은 놀랍게도 멈추지 않았다. 나는 그 과정을'kill -9'해야만했다. "killall java"도 작동하지 않았습니다. – Arin

+0

그것은 나를 위해 일했다. 하지만 슬프게도이 버그/실패로 인해 면역이 무산 될 수 있다고 생각합니다. – Tatarize

관련 문제