0

i wrote an Application of a simple counter, nothing more. My GUI has a Label and 1 Button for the start/stop function. My EventHandler of the button looks like this:

b_start.setOnAction((ActionEvent e) ->{
        if(!clock.isRunning()){
            clock.setRunning(true);
            b_start.setText("Stop");
            b_start.setStyle("-fx-background-color: red");
        }else{
            clock.setRunning(false);
            b_start.setText("Start");
            b_start.setStyle("-fx-background-color: lightgreen");
        }   
    });

--Clock.java

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package logic;

import java.util.Observable;

/**
 *
 * @author
 */
public class Clock extends Observable implements Runnable {

    private String zeit = "";
    private int sek;
    private boolean isRunning = false;

    public Clock() {

    }

    public void setZeit() {
        zeit = "" + sek;
    }

    public String getZeit() {
        return zeit;
    }

    public void setRunning(boolean running){
        this.isRunning = running;
    }

    public boolean isRunning(){
        return isRunning;
    }

    public int getSek() {
        return sek;
    }

    @Override
    public void run() {
        while (true) {
            System.out.println();
            if (isRunning()) {
                try {
                    sek++;
                    setZeit();
                    System.out.println();
                    this.setChanged();
                    this.notifyObservers();
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    //TODO
                }
            }
        }
    }
}

Right now, this code isnt working. Seems like the if()- clause isnt reachable but isRunning() returns "true".. (Tested with System.out.println)

Another way:

@Override
public void run() {
    while (true) {
        System.out.println(); //ADDING THIS -> CODE WORKS //DELETE THIS ->    //CODE WONT WORK
        if (isRunning()) {
            try {
                sek++;
                setZeit();
                this.setChanged();
                this.notifyObservers();
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                //TODO
            }
        }
    }
}

Why do i have to make the isRunning method synchronized//Why can i add a simple System.out.println() to make the code do what it has to?

Tjatte
  • 251
  • 4
  • 14
  • Usually, GUI toolkits (AWT, Swing, JavaFX) start their threads. `synchronized` makes the method runnable by **one thread at a time**. Otherwise, a method may be entered by many threads at once, which may cause random errors to occur. – Top Sekret Jul 04 '16 at 20:50
  • Thanks for your answer, but that wasnt the one i was looking for. I know, that synchronized makes the method runnable by one thread at a time. I dont know, but after setRunning(true), the boolean running is true but i cant enter the if(isRunning()) clause. – Tjatte Jul 04 '16 at 20:56
  • that `System.out.println()` line is enough to drive someone crazy haha :D – niceman Jul 04 '16 at 21:03
  • Also, read this: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility – JB Nizet Jul 04 '16 at 21:17
  • Sorry, wrong duplicate (.net rather than Java). See http://stackoverflow.com/questions/21135870/why-does-java-not-see-the-updated-value-from-another-thread – JB Nizet Jul 04 '16 at 21:18
  • I understood it, finally.. Thanks for your help guys ;) & sorry for duplicate – Tjatte Jul 04 '16 at 21:21
  • still there is `System.out.println()`, why adding this statement make it work ? – niceman Jul 04 '16 at 21:44
  • Have a look at this, niceman: http://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement – Tjatte Jul 04 '16 at 22:12

0 Answers0