# new Thread oder setRunning = true/false



## Crisma (22. Dez 2013)

Hallo,

ich habe mal eine Frage zu den Threads:
Ich habe einen Thread, den ich pausieren möchte. Jetzt gibt es ja zwei Möglichkeiten (evtl auch mehr?!?).
Zum einen könnte ich den Thread beenden und dann bei bedarf wieder einen neuen starten, oder aber ich nehme mir einen setter und setze ein Boolean jeweils auf true oder false in der Schleife in der run-Methode.

Gibt es da jetzt eine Methode, die mehr zu empfehlen wäre? Auch von der Performance her?
Oder ist das eher Geschmackssache?

Grüße,
C.


----------



## Rock45 (22. Dez 2013)

Es kommt darauf an wie du das Warten mit der Schleife gestaltest?

Also prinzipiell hast du die Möglichkeit den Thread zu beenden, oder dein Beispiel mit wait(); und notify(All)(); zu realisieren. 

Was schöner ist kommt darauf an, was das Programm wie oft machen muss. Wenn die Threads eh nichts zu tun haben und nur selten gebraucht werden bietet es sich an die Threads durchlaufen zu lassen und einen neuen zu erstellen. Ansonsten hab ich die wait und notify Methode lieber, wenn sich das Programm dementsprechend umsetzen lässt.


----------



## Crisma (25. Dez 2013)

Rock45 hat gesagt.:


> Es kommt darauf an wie du das Warten mit der Schleife gestaltest?




```
while (true) {
if(isRunning) {
....
}
}
```
so läuft der Thread natürlich die ganze Zeit. 
Es ist ein simples Programm, was wiederholt einen Piep von sich gibt. Also der Thread an sich ist nicht sehr aufwändig. Ein paar getter und setter, evtl. noch nen Handler...

Meine Frage wäre ja nur, ob man sagt: ein Thread hat beendet zu werden, wenn man ihn nicht mehr braucht oder ob man sagt: ach, lass den doch weiter laufen...


----------



## Rock45 (25. Dez 2013)

Wenn der Thread zwischen drin schlafen gelegt wird, ist die einfache Variante mit einem boolean Wert natürlich kein Problem.

Die if Anweisung brauchst du dann aber nicht.

```
while(running)
{
    //mach was
    //Thread.sleep(amountOfTime);
}
```

In dem Fall musst du natürlich nicht jedes mal einen neuen Thread starten.


----------



## Crisma (27. Dez 2013)

Doch,
genau dann muss ich ja immer einen neuen Thread starten, weil das endgültige Durchlaufen der run() Methode ja den Thread beendet.


----------



## KSG9|sebastian (27. Dez 2013)

Deshalb sollst du ja ein Flag setzen..

```
private volatile boolean running = true;


void foo() throws Exception {
   Runnable r = new Runnable(){
      public void run(){
          while(running) { ... }
      }
   }
   new Thread(r).start();

   running = false;
   // jetzt wartet der Thread

   runnning = true;
   // jetzt läuft er wieder
}
```


----------



## Crisma (27. Dez 2013)

Also wenn running = false ist, wird die While-Schleife nicht weiter durchlaufen, somit die run-Methode komplett durchlaufen und der Thread beendet.
Oder hab ich da was übersehen?


----------



## KSG9|sebastian (27. Dez 2013)

Ok, ich glaub ich war zu undeutlich, sorry 

Im Thread lässt du eine Endlosschleife laufen, und innerhalb der Endlosschleife prüfst du mittels "running" ob gearbeitet werden soll oder nicht



```
private volatile boolean running = true;
 
 
void foo() throws Exception {
   Runnable r = new Runnable(){
      public void run(){
          while(true) { 
             if(running) { .. } else { Thread.sleep(500); }
          }
      }
   }
   new Thread(r).start();
 
   running = false;
   // jetzt wartet der Thread
 
   runnning = true;
   // jetzt läuft er wieder
}
```


----------



## Crisma (27. Dez 2013)

ja gut,
aber genau so hatte ich es bereits im dritten Post hier beschrieben


----------



## KSG9|sebastian (27. Dez 2013)

Ich wür's so machen - gibt keinen Grund jedesmal den Thread zu verwerfen...zudem sieht es so "schöner" aus.


----------



## turtle (27. Dez 2013)

Ich habe mal eine kleine Demo geschrieben, die hoffentlich das ist, was du meintest.

Hier wird in einem Thread der Text auf einem Button hochgezählt. Über den Pause-Button kannst du den Thread pausieren und wieder weiter laufen lassen.
i
	
	
	
	





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

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Pause extends JPanel {
	public Pause() {
		setLayout(new BorderLayout());
		final JButton btnStart = new JButton("Start");
		final Counter counter1 = new Counter(btnStart, 1000);
		btnStart.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				CountDownLatch q = new CountDownLatch(1);
				Thread t1 = new Thread(counter1);
				t1.start();
			}
		});
		add(btnStart, BorderLayout.NORTH);
		JButton btnStop = new JButton("Pause");
		btnStop.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				counter1.pause();
			}
		});
		add(btnStop, BorderLayout.SOUTH);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Tick");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new Pause());
		frame.pack();
		frame.setVisible(true);

	}
}

class Counter implements Runnable {
	private final int delay;
	private final JButton btn;
	private volatile boolean pause;

	public Counter(JButton btnStart, int delay) {
		this.btn = btnStart;
		this.delay = delay;
		this.pause = false;
	}

	public void pause() {
		pause = !pause;
	}

	@Override
	public void run() {
		try {
			int i = 0;
			while (true) {
				if (!pause) {
					i++;
					btn.setText("" + i);
					Thread.sleep(delay);
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}
```


----------



## Crisma (27. Dez 2013)

Hallo Turtle,

vielen Dank, das ist wirklich sehr nett von Dir.
Aber ich wollte eigentlich wissen, ob ich einen Thread laufen lassen kann oder ihn doch eher immer wieder beenden und einen neuen starten sollte. Besonders im Falle von Android und Performance Fragen.

Es ging mir da eher um Konventionen und do's and dont's.
Im Grunde mache ich es ja derzeit auch genau so, wie Du es beschrieben hast.


----------



## turtle (28. Dez 2013)

Es sollte ja klar sein, einen Thread laufen zu lassen, der eigentlich nichts macht, sondern nur wartet, nennt man "busy waiting".

Ob dies Sinn macht, kannst nur du beurteilen. Ist die Erzeugung eines Threads und/oder das Laufenlassen bis zur gleichen Position von dem Thread, den du vielleicht abbrichst,teuer, ist abzuwägen. Oder kann man busy waiting verantworten, weil es eh nur für ein paar Sekunden dauert?

Das ist aber je nach Szenario unterschiedlich zu beantworten.

Wenn es sinnvoll scheint, den Thread NICHT abzubrechen, gibt es im Package java.util.concurrent eine Fülle von Klassen, die einen Thread schlafen legen und somit keine CPU verbrauchen und wieder laufen lassen. (beispielsweise CyclicBarrier oder Semaphore).

Wie ich schon sagte, kannst nur du sagen, welche Strategie in deinem Fall sinnvoll ist.


----------

