Watchdog

Hallo, ich hab da mal eine Frage und zwar wie schaff ich es das der Watchdog den Thread beendet? Also so dass das Ping Pong nach der angegebenen Zeit stoppt.

		boolean isPing=false;
		Object lock;
		String name;
		String s="/n";

		public PingPongsyn(Object lock, boolean isPing,String name) {
			this.lock = lock;
			this.isPing = isPing;
			this.name=name;
		}
		
		public PingPongsyn(String name,boolean isPing, Object lock){
			this.name=name;
			this.isPing=isPing;
			this.lock=lock;
		}
		
		public void isPing(){
			this.isPing=true;
		}
		
		public void isnotPing(){
			this.isPing=false;
		}

		public void pingPong()throws Exception{
			synchronized(lock){
				while(true){
					if (isPing){
						System.out.println(this.name);			
					lock.notifyAll();
					lock.wait();
				}else{
			
				}
		}
			}
	}

		public void run() {
			try {
				pingPong();
			} catch (Exception e) {
			}
		}
}```

```public class WatchDogsyn extends Thread {
	
		public static final int DAUER=500; //Dauer in msec
		private PingPongsyn t;
		private int dauer; //Dauer in msec
		Object z;
		/**
		 * Standard-Konstruktur
		 * @param t Thread, der abgebrochen werden soll
		 */
		public WatchDogsyn(PingPongsyn t) {
			this(t,DAUER);
		}

		/**
		 * Konstruktur mit Angabe der Ausführungsdauer
		 * @param t Thread, der abgebrochen werden soll
		 * @param dauer Länge der Ausführung in msec
		 */

		public WatchDogsyn(PingPongsyn t, int dauer) {
			this.t=t;
			this.dauer=dauer;
		}

		/**
		 * Threadinhalt: Abbruch des referenzierten Threads
		 */

		public void run() {
			try {
				sleep(dauer);
				t.isnotPing();
			} catch (InterruptedException e) {				
			}
		}
	}
	public static void main(String[] args) {
		Object o = new Object();
		PingPongsyn p1=new PingPongsyn("Ping",true,o);
		PingPongsyn p2=new PingPongsyn("Pong",true,o);
		p1.start();
		p2.start();
		new WatchDogsyn(p1,2000).start();
	    new WatchDogsyn(p2,2000).start();
		// (new PingPongsyn(o, true,"Ping")).start();
		// (new  PingPongsyn(o, true,"Pong")).start();
		// new WatchDogsyn(o,5000).start();
	}
}

Hi,

hier findest du Grundlagen zu dem Thema Threads:

http://openbook.galileocomputing.de/javainsel9/javainsel_14_003.htm#mjd0f19999270d6e1fbfd4af3a16273eef

Da du in diener while Schleife „True“ als Bedinung hast, wirst du diesen Thread niemals beenden können. Man kann stop() callen, aber das ist deprected und auch nicht gerade toll auf diese Weise dem Thread einen Dolch in den Rücken zu rammen. Man weiß nicht, was er gerade macht und PUFF dead.

in die While-Schleife sollte man ein „isInterrupted“ callen und dann von außen „interrupt()“ aufrufen.

Gruß,

Martin

Ich bekomm es irgendwie noch immer nicht hin :/. Ich frag jetzt in der Schleife mit isInterrupted() ab und der Thread wird auch nach 2 Sekunden beendet, da ich in der Klasse WatchDog den Thread mit t.interrupt() beende, jedoch wird mir das Ping Pong nicht mehr angezeigt. Was mach ich falsch? Sorry bin noch ein ziemlicher Anfänger :confused:

Öhhh… Der Thread wird beendet, ich hätte erwartet, dass das PING PONG aufhört. Der Thread soll beendet werden und das Ping Pong soll weiter gehen?

Naja der Thread läuft irgendwie aber in der Console erscheint kein Ping Pong, danach wird er nach 2 Sekunden beendet. Wenn ich jedoch in der Schleife !isInterrupted() schreibe, erscheint das Ping Pong in der Konsole aber er wird nicht beendet.

Poste vielleicht nochmal den letzten Stand des geänderten Codes, und eine klare, genaue Beschreibung des beobachteten und des erwarteten Verhaltens.

Alles Klar, also hier frage ich mit isInterrupted() ab:

		boolean isPing=false;
		Object lock;
		String name;
		String s="/n";

		public PingPongsyn(Object lock, boolean isPing,String name) {
			this.lock = lock;
			this.isPing = isPing;
			this.name=name;
		}
		
		public PingPongsyn(String name,boolean isPing, Object lock){
			this.name=name;
			this.isPing=isPing;
			this.lock=lock;
		}
		
		public void isPing(){
			this.isPing=true;
		}
		
		public void isnotPing(){
			this.isPing=false;
		}

		public void pingPong()throws Exception{
			synchronized(lock){
				while(isInterrupted()){
					try{
					System.out.println(this.name);
					lock.wait();
					lock.notify();
					}catch (Exception e) {
						// TODO: handle exception

					 }
				} 
			}
	} 

		public void run() {
			try {
				pingPong();
			} catch (Exception e) {
			}
		}
}```

Der Watchdog soll den Thread mit t.interrupt() beenden: 

``` public class WatchDogsyn extends Thread {
	
		public static final int DAUER=500; //Dauer in msec
		private PingPongsyn t;
		private int dauer; //Dauer in msec
		Object z;
		/**
		 * Standard-Konstruktur
		 * @param t Thread, der abgebrochen werden soll
		 */
		public WatchDogsyn(PingPongsyn t) {
			this(t,DAUER);
		}

		/**
		 * Konstruktur mit Angabe der Ausführungsdauer
		 * @param t Thread, der abgebrochen werden soll
		 * @param dauer Länge der Ausführung in msec
		 */

		public WatchDogsyn(PingPongsyn t, int dauer) {
			this.t=t;
			this.dauer=dauer;
		}

		/**
		 * Threadinhalt: Abbruch des referenzierten Threads
		 */

		public void run() {
			try {
		
				sleep(dauer);
				System.out.println("fertig");
			} catch (InterruptedException e) {
				t.interrupt();			
			}
		}
	}

Zunächst sehe ich gar nichts auf der Konsole, nach 2 Sekunden bekomme ich ein “Fertig” in der Konsole und den Status

Ich möchte aber das in der Konsole ständig Ping Pong ausgegeben wird und nach 2 Sekunden soll es stoppen.

der Watchdog hat ein interrupt des zu watchenden Threads nur in einem catch, warum sollte das catch drankommen?
das muss normaler Code sein:

		try {
			sleep(dauer);
			System.out.println("fertig");
			t.interrupt();
		} catch (InterruptedException e) {
			throw new RuntimeException(e); // besser als gar nichts zu tun, 
                                 // sollte aber nie drankommen
		}
	}

im Ping-Thread hast du als Bedingung while(isInterrupted()) das ist am Anfang false, die Threads brechen sofort ab, andersrum sicher gemeint,

außerdem muss das notify() vor dem wait() stehen, hattest du ja auch am Anfang schon?
sonst geht ein Thread ins wait() hinein, der andere kommt dran, wait()ed dann auch und beide warten ewig,
versuche selber zu überlegen, wie der Ablauf mit den Befehlen andersrum sein kann

schließlich gibt es noch die Besonderheit zu bedenken, dass beim catch einer InterruptetException der interruptet-Status wieder auf false gesetzt wird, bzw. gar nicht erst auf true, deswegen würde die korrekte Schleife nach einem catch weiterlaufen,
entweder einen eigene boolean-Variable setzen oder nochmal interrupt(); aufrufen, was ein typisches Vorgehen ist

und damit du nicht tausende Meldungen bekommst, lohnt sich ein Warten von 100ms :

		synchronized (lock) {
			while (!isInterrupted()) {
				try {
					System.out.println(this.name);
					Thread.sleep(100);
					lock.notify();
					lock.wait();
				} catch (InterruptedException e) {
					interrupt();
				}
			}
			System.out.println("Ende: " + this.name);
		}
	}

Vielen Dank an alle, hab es endlich hin bekommen :slight_smile:

Am besten auch immer die Lösung posten, damit auch andere was davon haben :slight_smile:

habe ich doch getan :stuck_out_tongue_winking_eye: