//======================================================
// Fail TootjadTarbijad.java
//======================================================

import java.util.*;

/** Klassikaline tootja-tarbija ylesanne. */

public class TootjadTarbijad {

   static final int PUHVRIPIKKUS = 6;

   /** jagatav ressurss lo'imede vahel. */
   static Vector yhispuhver = new Vector (PUHVRIPIKKUS);

   /** peameetod. */
   public static void main (String[] parameetrid) {
      int tootja1_tiks  = 5000; //millisekundit
      int tootja2_tiks  = 7000; //millisekundit
      int tarbija1_tiks = 3000; //millisekundit
      Tootja  tootja1  =
         new Tootja  (yhispuhver, tootja1_tiks,  "Pro1");
      Tootja  tootja2  =
         new Tootja  (yhispuhver, tootja2_tiks,  "Pro2");
      Tarbija tarbija1 =
         new Tarbija (yhispuhver, tarbija1_tiks, "Con1");
      System.out.println
         ("Puhvri suurus: " + yhispuhver.capacity());
      tootja1.start();
      tootja2.start();
      tarbija1.start();
   } // main lopp

} // TootjadTarbijad lopp

/** Tootjalo'im. */

class Tootja extends Thread {

   /** viitab yhispuhvrile, kuhu tooted panna. */
   Vector puhver;

   /** toote tegemiseks vajalik aeg millisekundites. */
   int tiks;

   /** tootja kaubama"rk. */
   String nimi;

   /** tootjalo'ime loomine. */
   Tootja (Vector v, int i, String s) {
      puhver = v;
      tiks = i;
      nimi = s;
   }

   /** ylekaetud meetod - lo'ime sisu. */
   public void run() {
      try {
         while (true) { //lopmatu tsykkel
            tooda();    //iga tiksuga toodab uue asja
            sleep (tiks);
         }
      }
      catch (InterruptedException e) {
      }
   }

   /** yhe toote tootmine. */
   private void tooda()
      throws InterruptedException {
         synchronized (puhver) {
            while (puhver.size() >= puhver.capacity()) {
               puhver.wait(); //puhver on ta"is, oota
            }
            puhver.addElement ("(" + nimi + " > " +
               new Date().toString() + ")"); //ajatempel
            System.out.println (nimi + " > " + 
               puhver.lastElement() +
               " " + tiks + " " + puhver.size());
            puhver.notifyAll();
         } // kriitilise sektsiooni lopp
   }
} // Tootja lopp

/** Tarbijalo'im. */

class Tarbija extends Thread {
   
   /** yhispuhver, kust vo'tta. */
   Vector puhver;

   /** yhe toote tarbimiseks kuluv aeg millisekundites. */
   int tiks;

   /** tarbija identifikaator. */
   String nimi;

   /** tarbijalo'ime konstruktor. */
   Tarbija (Vector v, int i, String s) {
      puhver = v;
      tiks = i;
      nimi = s;
   }

   /** tarbijalo'ime sisu - ylekaetud meetod. */
   public void run() {
      try {
         while (true) { //lopmatu tsykkel
            tarbi();    //iga tiksuga tarbib u"he asja
            sleep (tiks);
         }
      }
      catch (InterruptedException e) {
      }
   }

   /** yhe toote tarbimine. */
   private void tarbi()
      throws InterruptedException {
         synchronized (puhver) {
            while (puhver.size() <= 0) {
               puhver.wait(); //oota, kuni midagi tekib
            }
            String teade = (String)puhver.firstElement();
            System.out.println (nimi + " < " +
               teade + " " + tiks);
            puhver.removeElementAt (0);
            puhver.notifyAll();
         } // kriitilise sektsiooni lopp
   }
} // Tarbija lopp

//====================
// faili lopp 
//====================
