/**************************************************************/
/* Prof. Dr. Carsten Vogt                                     */
/* FH Koeln, Fak. 07 / Nachrichtentechnik                     */
/* http://www.nt.fh-koeln.de/vogt                             */
/*                                                            */
/* synchronized:                                              */
/* Ein Objekt bietet eine Methode an, die 'synchronized' ist, */
/* d.h. die hoechstens von einem Thread gleichzeitig ausge-   */
/* fuehrt werden kann.                                        */
/**************************************************************/

class Monitor {

 /* Durch das Schlüsselwort 'synchronized' ist der Zugriff
    auf ein Objekt der Klasse 'Monitor' wechselseitig aus-
    geschlossen: Es darf jeweils hoechstens ein Thread in
    einer der mit synchronized markierten Methoden des Ob-
    jekts aktiv sein.
    Tipp: 'synchronized' loeschen und Programm nochmals aus-
    fuehren. */

 synchronized void ausgabeSchleife(String ausgabeText) {

  /* In der Methode gibt der Thread zehnmal hintereinander
     einen Text aus und wartet dazwischen jeweils fuer 100
     Millisekunden. */

  try {

   for (int i=0;i<10;i++) {
    System.out.println(ausgabeText);
    Thread.sleep(100);
   }

  } 
  catch (InterruptedException e) { }

 }

}


/* Thread, der auf ein Monitor-Objekt zugreift */

class EinThread extends Thread {

 private Monitor mon;  /* Monitor-Objekt, auf das zugegriffen wird. */
 private String ausgabeText; /* Text, der ausgegeben werden soll. */

 /* Konstruktor */ 

 EinThread(String ausgabeText,Monitor mon) {
  this.ausgabeText = ausgabeText;
  this.mon = mon;
 }

 /* run()-Methode mit Aufruf der Monitor-Methode */

 public void run() {
  mon.ausgabeSchleife(ausgabeText);
 }

}


/* Hauptprogramm */

public class ThreadSyncMitMonitor {

 public static void main(String[] args) {

  /* Erzeugung des Monitor-Objekts, auf dem beide Threads arbeiten sollen. */

  Monitor mon  = new Monitor();

  /* Erzeugung und Start zweier Threads, die mit dem Monitor arbeiten. */

  EinThread T1 = new EinThread("T1",mon);
  EinThread T2 = new EinThread("   T2",mon);

  T1.start();
  T2.start();
  
 }

}

