Zatrzymanie pętli while.

0

Witam. Dlaczego w pierwszej wersja(patrz pętla while) zadziała zatrzymanie pętli, a w drugiej i trzeciej pętla się nie zatrzyma? Zależy mi na tym aby zakończyć pętle while wykonywaną w osobnym wątek przy pomocy przycisku. Pozdrawiam.

public class Tex implements Runnable{
    

    JavaFX_Thread ty;
    
    public Tex(JavaFX_Thread ty){
        
        this.ty=ty;
        System.out.println("UTWORZENIE OBIEKTU!");

    }
        
    @Override
    public void run(){
       
        System.out.println("RUN");
        
        while(ty.isB()){
            
            //1: DZIAŁA      System.out.println(ty.isB()); 
            //2: NIE DZIAŁA  ty.isB();
            //3: 
 
        }

        System.out.println("PĘTLA STOP");
    }
    
}

 
public class JavaFX_Thread extends Application {
    
    Tex tex;
    Thread thread;
    private boolean b;

    @Override
    public void start(Stage primaryStage) {

        Button btn = new Button("Start");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                
                b=false;
            }
        });
        
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("Test");
        primaryStage.setScene(scene);
        primaryStage.show();
        
        b=true;
        tex=new Tex(this);
        thread = new Thread(tex);
        thread.start();
        System.out.println("START WĄTKU");
    }

    public boolean isB(){

        return b;
    }
}
 
2
Java_Noob napisał(a):

zobacz z taką zmianą:

private volatile boolean b;
0

Dzięki teraz działa bezbłędnie:) Nadal nie rozumiem dlaczego to działało prawidłowo tylko jak wyświetlałem w konsoli aktualna wartość b. W innym wypadku mogłem sobie klikać ten przyciski i 100 razy, a i tak pętla się nie kończyła pomimo tego że b przez cały czas miało wartość false...

1
Java_Noob napisał(a):

Dzięki teraz działa bezbłędnie:) Nadal nie rozumiem dlaczego to działało prawidłowo tylko jak wyświetlałem w konsoli aktualna wartość b. W innym wypadku mogłem sobie klikać ten przyciski i 100 razy, a i tak pętla się nie kończyła pomimo tego że b przez cały czas miało wartość false...

Upraszczając:
Możesz sobie wyobrazić, że wątki w javie działają troche jak osobne programy z osobna pamięcią! Jeśli w jednym z nich zmienisz b - to drugi nie musi tego widzieć - tylko widzi starą wartość!
Aby wymusić przesłanie zmian między wątkami deklarujesz zmiennną jako volatile - to znaczy, ze przed każdym odczytem wątek zsynchronizuje wartość z innymi wątkami).
Podobnie działa użycie synchronized (..) { }.

0

@jarekr000000: ja prdl, jesteś żywym JVM! Ucz mnie mistrzu!

1 użytkowników online, w tym zalogowanych: 0, gości: 1