/**************************************************************/
/* Prof. Dr. Carsten Vogt                                     */
/* FH Koeln, Fak. 07 / Nachrichtentechnik                     */
/* http://www.nt.fh-koeln.de/vogt                             */
/*                                                            */
/* Durchsetzung einer Reihenfolgebeziehung mit Semaphor:      */
/* Seit der Version 5 stellt Java die Klasse "Semaphor" zur   */
/* Verfuegung.                                                */
/**************************************************************/

import java.util.concurrent.*;

class Vorgaenger extends Thread {

 private Semaphore sem;
  /* Semaphor, ueber den der Thread sich mit dem Nachfolger synchronisiert. */

 Vorgaenger(Semaphore sem) {
  this.sem = sem;
 }

 public void run() {
  try {
   System.out.println("Vorgaenger: Start"); 
   /* Erst 3 Sekunden warten ... */
   sleep(3000);
  /* ... und dann den Nachfolger benachrichtigen */
  System.out.println("Vorgaenger: Nachfolger weiterlaufen lassen durch sem.release()"); 
  sem.release();
  System.out.println("Vorgaenger: Weiterlaufen");
  sleep(2000);
  System.out.println("Vorgaenger: Ende"); 
  } catch (Exception e) { }
 }

}

/* Nachfolger-Thread */

class Nachfolger extends Thread {

 private Semaphore sem;
  /* Semaphor, ueber den der Thread sich mit dem Vorgaenger synchronisiert. */

 Nachfolger(Semaphore sem) {
  this.sem = sem;
 }

 public void run() {
  try {
   System.out.println("Nachfolger: Start"); 
   System.out.println("Nachfolger: Warten durch Semaphore.acquire()");
   sem.acquire(); 
   System.out.println("Nachfolger: Weiterlaufen"); 
   sleep(3000);
   System.out.println("Nachfolger: Ende"); 
  } catch (Exception e) { }
 }

}

/* Hauptprogramm */

class ThreadReiheMitSemaphor {

 public static void main(String[] args) {

  /* Erzeugung des Semaphor-Objekts zur Durchsetzung der Reihenfolgebeziehung. */

  Semaphore sem  = new Semaphore(0);

  /* Erzeugung und Start zweier Threads, die sich ueber den Semaphor synchronisieren. */

  Vorgaenger t1 = new Vorgaenger(sem);
  Nachfolger t2 = new Nachfolger(sem);

  t1.start();
  t2.start();
  
 }

}
