2012-04-07 15 views

Odpowiedz

4

Nie od razu po wyjęciu z pudełka, nie. Normalnie program Reader zerwa tylko z wywołania read(), gdy inny wątek zamknie strumień bazowy lub dojdziesz do końca danych wejściowych.

Ponieważ read() nie jest to wszystko, co jest przerywane, staje się to nieco współbieżnym problemem programistycznym. Wątek, który wie o przekroczeniu limitu czasu, musi być w stanie przerwać wątek, który próbuje odczytać dane wejściowe.

Zasadniczo, wątek do czytania będzie musiał sondować metodę ready() czytnika, zamiast blokować go w read(), gdy nie ma nic do czytania. Jeśli otoczysz tę operację odpytywania i oczekiwania w java.util.concurrent.Future, wywołasz metodę get() Future z limitem czasu.

Ten artykuł przechodzi w niektórych szczegółach: http://www.javaspecialists.eu/archive/Issue153.html

12

nieznacznie łatwiejszy sposób to zrobić, niż odpowiedzi Benjamin Coxa byłoby zrobić coś takiego

int x = 2; // wait 2 seconds at most 

BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
long startTime = System.currentTimeMillis(); 
while ((System.currentTimeMillis() - startTime) < x * 1000 
     && !in.ready()) { 
} 

if (in.ready()) { 
    System.out.println("You entered: " + in.readLine()); 
} else { 
    System.out.println("You did not enter data"); 
} 

Będzie to jednak zużywa więcej zasobów niż jego rozwiązanie .

+2

Funkcja BufferedReader.ready() wydaje się zwracać wartość true, jeśli dostępne są jakieś bajty, niekoniecznie zawierające znak nowej linii. Rozważmy przypadek, w którym czeka na Ciebie jeden znak bez kończącej się nowej linii. in.ready() zwraca wartość true, wywołuje funkcję in.readLine(), ale blokuje bezterminowe oczekiwanie na znak nowej linii. – pendor

+1

@pendor Ale standardowe "System.in" będzie tylko dane, jeśli użytkownik trafi enter w wierszu polecenia, który zapewnia sekwencję nowej linii. – Jeffrey

+1

@Jeffrey jest to udokumentowane w dowolnym miejscu? – Max

Powiązane problemy