# Frage zur Run Methode!



## dapor (28. März 2005)

Hi,

ich habe meine eigene Runmethode geschrieben.
Sie soll eine Art Timer darstellen und deshalb von 10 auf 0 runterzählen und nach einer Sekunde halt immer repaint() aufrufen.
Fkt soweit auch wunderbar, aber da der Benutzer des Programms den Countdown manuell abbrechen kann, ist eine mir unklare Sache aufgetreten.
Der Thread schläft ja immer eine Sekunde, bevor er wieder alles neu zeichnet! Wenn der Benutzer den Thread jetzt anhält durch eine bestimmt Aktion (also die zeitBoo Variable auf false und ZeitAnzahl auf -1 gesetzt) und innerhalb von 1 Sekunde wieder den Thread startet durch eine andere Aktion, dann setzt er zwar den  Timer auf 10, aber er wartet nicht mehr 1 Sekunde bis er auf 9 geht, sondern nur noch die Restmillisekunden die vom alten Thread übriggeblieben waren.

Zur Veranschaulichung hier der Code der RunMethode

```
public void run() {
        while (true) {
            if (ZeitBoo == true) {
                try {                
                    Zeit.sleep(1000);
                } catch (InterruptedException e) {
                    //falls ein Fehler auftritt
                }
                repaint();
                ZeitAnzahl--;            
                if (ZeitAnzahl == -1) {
                    Fertig();
                }
            }
        }
        
    }
```

Außerdem passiert es manchmal (sehr selten), dass er eine Sekunde nicht darstellt und beispielsweise gleich von 9 auf 7 springt.

Wie kann ich beide Probleme beheben? Vor allem möchte ich, dass wenn ich die Boolean Variable ZeitBoo auf true setze, er dann wirklich neu beginnt und von 10 auf 0 runterzählt und immer 1 Sekunde genau wartet.


----------



## Thomas Darimont (28. März 2005)

Hallo!

Wie wäre es denn, wenn du:

```
try {                
                    Zeit.sleep(1000);
                } catch (InterruptedException e) {
                    //falls ein Fehler auftritt
                }
```

hinter den if-Block:

```
if (ZeitAnzahl == -1) {
                    Fertig();
                }
```

legen würdest?

Gruß Tom


----------



## dapor (28. März 2005)

Das Problem ist ja das ich von einer anderen Klasse aus die Boolean Variable auf false setze und auch in der anderen Klasse sie wieder auf true setzen kann.
Das Problem ist bloss wie gesagt, wenn dies innerhalb von 1 Sekunde alles passiert, dann ist das erste Zeitintervall von 10 auf 9 nur ein paar millisekundne und keine ganze Sekunde.

Und ist es zu erklären warum er manchmal direkt von 9 auf 7 geht und scheinbar vergisst bei 8 zu repainten? wie gesagt der 2te fehler tritt nur sehr sehr sporadisch auf!


----------



## Thomas Darimont (28. März 2005)

Hallo!


> Und ist es zu erklären warum er manchmal direkt von 9 auf 7 geht und scheinbar vergisst bei 8 zu repainten? wie gesagt der 2te fehler tritt nur sehr sehr sporadisch auf!



Das ist ein Timing Problem bei der Ablauflogik deines Programmcodes.

Schau mal hier:

```
/**
 * 
 */
package de.tutorials;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * @author Administrator
 * 
 */
public class Counter extends JFrame {

    private JButton btn;

    private JLabel lbl;

    private boolean pause;

    private int cnt = 10;

    private Thread runner = new Thread() {
        public void run() {
            while (true) {
                if (!pause) {

                    lbl.setText("" + cnt);
                    cnt--;

                    if (cnt < 0) {
                        fertig();
                        break;
                    }

                    try {
                        sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        sleep(100L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };

    public Counter() {
        super("Counter");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        btn = new JButton("action");
        btn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pause = !pause;
            }
        });

        lbl = new JLabel("   ");

        add(btn, BorderLayout.WEST);
        add(lbl, BorderLayout.EAST);

        pack();
        setVisible(true);
        runner.start();
    }

    private void fertig() {
        System.out.println("fertig");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new Counter();
    }
}
```

HTH,
Gruß Tom


----------



## dapor (28. März 2005)

ah dankeschön
bis jetzt kam der Fehler nicht mehr, als ich es verändert habe (also der zweite Fehler)!
Für den anderen Fehler habe ich es jetzt so gemacht, dass der User erst wieder an anklicken kann, wenn die Zeit abgelaufen ist. So umgehe ich das einfach. Ist zwar nicht im Sinne des Erfinders aber es funktioniert! 

EDIT: Ok zu früh gefreut, habe es so geändert wie in deinem Bsp leider passiert es trotzdem manchmal noch, aber egal ich übersehe es am besten.


----------

