/***************************************************************/
/* Prof. Dr. Carsten Vogt                                      */
/* FH Koeln, Fak. 07 / Nachrichtentechnik                      */
/* http://www.nt.fh-koeln.de/vogt                              */
/*                                                             */
/* setPriority():                                              */
/* Das Programm startet zwei Threads "Thread 1" und "Thread2". */
/* Zunaechst bekommt Thread 1 eine niedrige und Thread 2 eine  */
/* hohe Prioritaet. Nach zwei Sekunden bekommen beide Threads  */
/* dieselbe Prioritaet und schliesslich bekommt Thread 1 eine  */
/* hohe und Thread 2 eine niedrige Prioritaet.                 */
/***************************************************************/

class BasicThread extends Thread {

 /* Der Thread laeuft in einer Endlosschleife, gibt jeweils
    einen Text aus und durchlaeuft zwischen den Ausgaben zwei
    zeitaufwendige geschachtelte Schleifen (je Durchgang
    10 Mio. Schleifendurchlaeufe). */

 String text; /* Auszugebender Text */

 /* Konstruktor: Setzen des auszugebenden Texts */

 BasicThread(String t) {
  text = t;
 }

 /* Aktionen: Textausgaben und zwischendurch Durchlauf durch
    die zeitaufwendigen Schleifen. */

 public void run() {
  int i,j;
   while (true) { 
    System.out.println(text);
    /* Die folgenden geschachtelten Schleifen dienen zur
       Erzeugung einer CPU-Belastung. Wenn sie weggelassen
       werden und der Thread nur noch Bildschirmausgaben macht,
       funktioniert das Programm nicht mehr. */
    for (i=1;i<10000;i++)
     for (j=1;j<1000;j++);
   }
 }
}

class Controller extends Thread {

 /* Der Controller startet zwei Threads von Typ "BasicThread"
    und aendert in bestimmten Zeitabstaenden ihre Prioritaeten. */

 /* zu kontrollierende "BasicThreads" */
 BasicThread t1;
 BasicThread t2;

 /* Konstruktor: Setzen der zu kontrollierenden BasicThreads,
    die durch das rufende Programm in den Konstruktorparametern
    t1 und t2 uebergeben werden. */

 Controller(BasicThread thr1, BasicThread thr2) {
  t1 = thr1; t2 = thr2;
 }

  /* Aktionen: */

 public void run() {

  try {
 
   /* Hoechste Prioritaet fuer den Controller */
   this.setPriority(Thread.MAX_PRIORITY);

   System.out.println();
   System.out.println("Thread 1 niedrige Prio, Thread 2 hohe Prio");   
   sleep(2000);
   t1.setPriority(Thread.MIN_PRIORITY);
   t2.setPriority(Thread.MAX_PRIORITY-1);
    
   /* Starten der Threads */ 
   t2.start();
   t1.start();
   sleep(1000);

   /* Prioritaetenwechsel */
   System.out.println();
   System.out.println("### PRIOWECHSEL ###");
   System.out.println("Beide Threads hohe Prio");   
   t1.setPriority(Thread.MAX_PRIORITY-1);
   sleep(2000);

   /* Prioritaetenwechsel */
   System.out.println();
   System.out.println("### PRIOWECHSEL ###");
   System.out.println("Thread 1 hohe Prio, Thread 2 niedige Prio");   
   t2.setPriority(Thread.MIN_PRIORITY);

  } catch (java.lang.InterruptedException E) { }
 
 }
}

public class Priorities {

 /* Hauptprogramm */

 public static void main(String[] args) {

  System.out.println();
  /* Erzeugen der Threads */
  BasicThread thread1 = new BasicThread("    hier ist thread 1");
  BasicThread thread2 = new BasicThread("HIER IST THREAD 2");
  Controller cont = new Controller(thread1,thread2);
    /* cont soll thread1 und thread2 kontrollieren,
       d.h. ihre Prioritaeten setzen */

  /* Ausgabe der numerischen Werte
     der niedrigsten und hoechsten Prioritaet */
  System.out.println();
  System.out.println("MIN_PRIORITY = "+Thread.MIN_PRIORITY);
  System.out.println("MAX_PRIORITY = "+Thread.MAX_PRIORITY);

  /* Starten des Controllers, der seinerseits die beiden
     anderen Threads startet */
  cont.start();

 }
}

