Witam!
Mam mały problem na który nigdzie nie mogę znaleźć odpowiedzi. Mam pętle nieskończoną for(;;) i chciałbym zrobić tak aby po naciśnięciu klawisza np 0 wyrzuciło mnie z tej pętli. Zaznaczam ,że zależy mi na tym aby program nie oczekiwał po każdym przejściu pętli reakcji użytkownika i wymuszał naciśnięcie przycisku. Pobieranie zmiennej potrzebnej do wyrzucenia z pętli powinno odbywać się tak jakby w ukryciu. Nie tworzę tego w GUI . Będę wdzięczny za każdą poradę.
Stwórz nowy wątek (Thread - pogooglaj) i tam oczekuj na wpisanie "0". Gdy to się stanie, to ustaw jakąś zmienną (flagę) w klasie, która ma tego for'a nieskonczonego i w kazdym obrocie pętli sprawdzaj wartość tej flagi. Użyj AtomicBoolean jako typu flagi.
System.in udostępnia metodę available() i jeśli sobie to opakujesz np w BufferedReader to będzie metoda ready(). Być może to wystarczy.
Ale wejście jest wciąż buforowane, więc minimum "0[enter]".
Jakoś sobie poradziłem ale mam następny problem. Pomija mi break w if ;/ if na pewno się wykonuje bo wstawiłem System.out.println z wiadomością która zostaje wyrzucana na ekran ale break jest pomijany... Miał ktoś taki przypadek ?
jeśli masz podwójną pętle to zawsze z tej najbardziej wewnętrznej jedynie wychodzi
Zrobiłem przykład. Bardzo możliwe ,że coś schrzaniłem tam bo mało wiem jeszcze o javie. Jeśli naciśnie się 0 break działa natomiast jeśli najpierw wciśnie się 2 a dopiero później 0 break jest pomijany. Mógłby mi ktoś to wytłumaczyć dlaczego tak jest ?
import java.util.Scanner;
class watek extends Thread{
int a=1;
public void run(){
Scanner in=new Scanner(System.in);
a=in.nextInt();
}
}
public class Main {
public void cos()
{
watek w=new watek();
w.start();
for(;;)
{
if(w.a==2)
{System.out.println("jeszcze raz");
cos();}
if(w.a==0)
{
System.out.println("koniec");
break;}
}
}
public static void main(String[] args) {
Main a=new Main();
a.cos();
}
}
na oko w wątku, w run, również powinieneś zrobić pętlę, bo wątek, zakańcza się po wczytaniu liczby
Już zrobiłem. Wystarczyło w pętli wywoływanej przez 2 po run() dodać break :) działa teraz przydało by się rozkminić dlaczego tak jest. Dzięki wszystkim za poświęcony czas
slawek napisał(a)
Już zrobiłem. Wystarczyło w pętli wywoływanej przez 2 po run() dodać break :) działa teraz przydało by się rozkminić dlaczego tak jest. Dzięki wszystkim za poświęcony czas
poprawka... po cos() nie po run()
jak na mnie to:
if(w.a==2)
{System.out.println("jeszcze raz");
cos();}
powinno być:
if(w.a==2)
{
System.out.println("jeszcze raz");
w.start(); // albo restart albo jakas inna metoda ktora odpala watek ponownie
}
ale jeśli w pętli jest odpalany cos() od początku to nie jest przypadkiem także wątek odpalany jeszcze raz ? jak na razie raczkuje w tym temacie. Jak wstawiłem break to wszystko dobrze działa tak jak zakładałem tylko pytanie dlaczego ? resetowany jest poprzedni cos() ?
Bez break w pętli wywoływanej 2 jest taki przebieg ... uruchamiany program--> wciskam 2 (działa wszystko)--> wciskam 0 ( wchodzi w pętle wywoływaną 0 ,wyrzuca komunikat z tej pętli , omija break, i w tym momencie jest dziwna sytuacja ponieważ wartość zmiennej a powraca do poprzedniego stanu czyli 2 i wchodzi pętla odpalaną 2 )
W sumie nie ma tu nic dziwnego.
Przy pierwszym odpaleniu cos wątek czeka na wprowadzenie jakiejś liczby, a ta pętla for(;;) lata w koło(żaden warunek jest niespełniony, więc nic nie robi).
Teraz jeżeli wpiszesz 0 to w.a będzie równe 0 i wyjdzie z pętli.
Jednak gdy wpiszesz 2 to odpali się kolejny wątek, który oczekuje na wprowadzenie liczby. Ten główny z pętlą lata dalej w koło, a że a jest równe 2 to tworzy w nieskończoność kolejne wątki i każdy oczekuje na jakąś liczbę. Nawet jak dasz radę i wyprzedzisz tworzenie wątków wpisując 0 setki razy w ciągu sekundy to i tak główny się nigdy nie zakończy. Każdy następny wątek pobiera liczbę z wejścia i wpisuje do a, ale dla każdego wątku to a jest zupełnie inne, to są różne zmienne. zmienna w ma zasięg lokalny tylko metody cos, kolejne jej wywołanie tworzy zupełnie nowy obiekt w.
Dzięki za wytłumaczenie. A dlaczego break w tym miejscu wszystko naprawia ? co on tak naprawdę zatrzymuje ?
if(w.a==2)
{System.out.println("jeszcze raz");
cos();
break; }
Break zatrzymuje najbliższą pętlę. Możesz mieć nawet 100 zagnieżdżonych if-ów, breaka to "nie interesuje".
bo funkcja cos wykonywana jest rekurencyjnie w nieskonczonosc. jesli na wejściu pojawi się koło 1 miliona dwójek to dostaniesz error: stack overflow
ok Dzięki wszystkim za poświęcony czas więcej pytań nie mam