thread anhalten und wieder starten

danielm

Erfahrenes Mitglied
hey,
also ich hab folgendes problem, ich möchte einen thread kurz anhalten, etwas anderes machen lassen und danach den thread wieder weiter laufen lassen

Code:
jmonc.Main.Status.suspend();
        socket.SendMsg(dialmode);
        jmonc.Main.Status.resume();

so hab ich mir das gedacht, der thread stoppt zwar, aber er läuft nicht wieder an... was mache ich da falsch?! :confused:

mfg daniel
 
danielm hat gesagt.:
Code:
jmonc.Main.Status.suspend();

Aua. So ein Code tut in der Seele weh. Schon mal was von OO, Kapselung und getter-setter gehört?

so hab ich mir das gedacht, der thread stoppt zwar, aber er läuft nicht wieder an... was mache ich da falsch?! :confused:

mfg daniel

Üblicherweise gibt es für Threads die Methoden start(), interrupt(), sleep() usw., steht alles in der API. Doort steht übrigens auch:

void resume()
Deprecated. This method exists solely for use with suspend(), which has been deprecated because it is deadlock-prone. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
 
naja, ich denke jmonc.Main.Status.suspend() hat schon was mit OO zutun...

aber wir bekomme ich dann den thread zum stoppen?!
 
Hallo!

Schau doch mal hier:
Code:
/**
 * 
 */
package de.tutorials;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Administrator
 * 
 */
public class ThreadExample {

	private boolean pause;

	private Object lock = new Object();

	private Thread runner = new Thread() {
		public void run() {
			int i = 0;
			while (true) {
				if (pause) {
					synchronized (lock) {
						try {
							lock.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				System.out.println(i++);

				try {
					sleep(500L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ThreadExample().doIt();
	}

	private void doIt() {
		runner.start();
		Timer timer = new Timer();
		TimerTask task = new TimerTask() {
			public void run() {
				pause = true;

				for (int i = 0; i < 10; i++) {
					System.out.print("bla: ");
					System.out.println(i);
					try {
						Thread.sleep(100L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				synchronized (lock) {
					lock.notify();
				}

				pause = false;
			}
		};
		timer.schedule(task, 5000L); // In 5 Sekunden starten...

	}

}

Gruß Tom
 
...oder mit Java 5 Mitteln:
Code:
/**
 * 
 */
package de.tutorials;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Administrator
 * 
 */
public class ThreadExample {

	private Lock lock = new ReentrantLock();

	private Thread runner = new Thread() {
		public void run() {
			int i = 0;
			while (true) {
				try {
					lock.lock();

					System.out.println(i++);

					try {
						sleep(500L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} finally {
					lock.unlock();
				}

			}
		}
	};

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ThreadExample().doIt();
	}

	private void doIt() {
		runner.start();
		Timer timer = new Timer();
		TimerTask task = new TimerTask() {
			public void run() {
			   try {
				lock.lock();
				for (int i = 0; i < 10; i++) {
					System.out.print("bla: ");
					System.out.println(i);
					try {
						Thread.sleep(100L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
   			   }finally{
				lock.unlock();
   			   }
			}
		};
		timer.schedule(task, 5000L); // In 5 Sekunden starten...

	}

}

Gruß Tom
 
danielm hat gesagt.:
naja, ich denke jmonc.Main.Status.suspend() hat schon was mit OO zutun...

Ehrlich gesagt nicht viel. Das sieht nach schlechtem C++ Ursprung aus, wie er leider immer wieder üblich ist und praktiziert wird.
 
Snape hat gesagt.:
Ehrlich gesagt nicht viel. Das sieht nach schlechtem C++ Ursprung aus, wie er leider immer wieder üblich ist und praktiziert wird.

naja, wie macht man es denn richtig? wir haben das so an der uni gelernt...
 
*Seufz* Ich weiß, dass an den Hochschulen sowas gelehrt wird. Du bist nicht der erste, nicht der einzige und sicher nicht der letzte, der nicht vernünftig OOP gelehrt bekommt.
Richtig wäre es, nicht auf die Objekte direkt zuzugreifen, sondern per get...() und ggf in Zwischenvariablen halten. Man mag durchaus anderer Auffassung sein und getter und setter nicht für notwendig erachten, wenn sie nur ein return meineVariable enthalten, aber es wäre sauber und konsequent OO.
Also besser - wenn auch noch fehlerträchtig, wenn die get-Methoden nicht sauber implementiert sind - wäre:

jmonc.getMain().getStatus().resume();

und die Steigerung
Main myMain = jmonc.getMain();
if (myMain != null)
Status myStatus = myMain.getStatus();
if ( myStatus != null )
myStatus.resume();

Außerdem gibt es noch die ganz saubere Möglichkeit:
Startklasse:
jmonc.resumeThread();

dessen Implementierung:

public void resumeThread()
{ getMain().resumeStatusThread() }

in Main:
public void resumeStatusThread()
{ getStatus().resumeYourThread() }

Und in Status:
public void resumeYourThread()
{ resume() }

Im OO-Sinne ist das letzte Beispiel sauber gekapselt und vorbildlich.
 
Hallo!

Im OO-Sinne ist das letzte Beispiel sauber gekapselt und vorbildlich.
In "deinem" OO-Sinne... man kanns auch übertreiben...

Wenn man sich im Sichtbarkeitsbereich von Membervariablen befindet braucht man IMHO keine getter zu bemühen. Das Geheimnisprinzip das dem Zugriff über getter und setter zugrunde liegt zählt meines erachtens nur für Fremde Objekte. Ein Argument für den Zugriff über setter oder getter auf Membervariablen der gleichen Instanz wäre etwa wenn dort noch weitere Logik getriggert werden würde (z.Bsp. wenn das Datum des letzten Zugriffs zwischengespeichert werden würde etc.)

Gruß Tom
 
Thomas Darimont hat gesagt.:
Hallo!


In "deinem" OO-Sinne... man kanns auch übertreiben...

Wenn man sich im Sichtbarkeitsbereich von Membervariablen befindet braucht man IMHO keine getter zu bemühen. Das Geheimnisprinzip das dem Zugriff über getter und setter zugrunde liegt zählt meines erachtens nur für Fremde Objekte. Ein Argument für den Zugriff über setter oder getter auf Membervariablen der gleichen Instanz wäre etwa wenn dort noch weitere Logik getriggert werden würde (z.Bsp. wenn das Datum des letzten Zugriffs zwischengespeichert werden würde etc.)

Gruß Tom


Hallo,

ich habe das ganze so gelernt:
Man soll nie auf die Eigenschaften einer Klasse (bzw. Objektes) direkt zugreifen. Es sollten immmer Methoden definiert werden, die das machen.

Wie weit er OOP umsetzt, ist aber meiner Meinung nach jedem selbst überlassen.
 
Zurück