new Thread oder setRunning = true/false

C

Crisma

Mitglied
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.
 
R

Rock45

Aktives Mitglied
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.
 
C

Crisma

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

Java:
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...
 
R

Rock45

Aktives Mitglied
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.
Java:
while(running)
{
    //mach was
    //Thread.sleep(amountOfTime);
}

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

Crisma

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

KSG9|sebastian

Top Contributor
Deshalb sollst du ja ein Flag setzen..
Java:
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
}
 
C

Crisma

Mitglied
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?
 
K

KSG9|sebastian

Top Contributor
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


Java:
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
}
 
K

KSG9|sebastian

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

turtle

Top Contributor
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
Java:
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();
		}
	}

}
 
C

Crisma

Mitglied
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

turtle

Top Contributor
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.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Von verschiedenen Klassen auf Thread zugreifen Android & Cross-Platform Mobile Apps 2
M Android Stop Swipe Refresh aus anderem Thread Android & Cross-Platform Mobile Apps 2
ms_cikar Thread / Intent als externe klasse Android & Cross-Platform Mobile Apps 1
G Thread in einer Service erstellen Android & Cross-Platform Mobile Apps 0
M App Programmierung: Thread starten und Variablenwerte oder Objekte mitgeben Android & Cross-Platform Mobile Apps 2
A Android Von einem Thread auf anderen zugreifen Android & Cross-Platform Mobile Apps 3
C Auf innere (Thread)Klasse zugreifen, von anderer Klasse aus Android & Cross-Platform Mobile Apps 3
S Android Kommunikation zwischen UI -> Service -> Thread Android & Cross-Platform Mobile Apps 4
G Pause ohne sleep und ohne zweiten Thread Android & Cross-Platform Mobile Apps 5
G Pause im Programmablauf ohne extra Thread Android & Cross-Platform Mobile Apps 2
JAVAnnik Android Layout ändern in Thread Android & Cross-Platform Mobile Apps 2
Gossi Android Gossis Android Fragen Thread Android & Cross-Platform Mobile Apps 3
H Android ListView Images aus dem Internet via Thread Android & Cross-Platform Mobile Apps 3
L Android Thread Android & Cross-Platform Mobile Apps 4
Kidao Wie startet man ein Thread richtig? Android & Cross-Platform Mobile Apps 4
G Thread und Midlet Android & Cross-Platform Mobile Apps 1
G Check Button ist unchecked trotz setChecked(true) Android & Cross-Platform Mobile Apps 6

Ähnliche Java Themen

Anzeige

Neue Themen


Oben