/*
 * Script 4.2 Exercise 9
 *
 * implement channel
 *
 */
/* output:

*/

import java.math.*;

class ex9prod implements Runnable {

  int l;

  public ex9prod(int li) {
    l = li; 
  }

  public void run() {

    BigInteger v, z;
    v = new BigInteger("1");
    z = new BigInteger("10");

    System.out.println("pw = " + l);

    for(int i=0; i<l; i++) {
          ex9.probe();
          v = v.multiply(z);
          ex9.chan.send(v);
    }

    synchronized (ex9.prn) { 
      System.out.println("         v  = " + v);
      System.out.println("         pd = " + l);
    }

  }
}

class ex9cons implements Runnable {

  int l;

  public ex9cons(int li) {
    l = li; 
  }

  public void run() {

    Object x;
    BigInteger v = new BigInteger("0");
 
    System.out.println("cw = " + l);

    for(int i=0; i<l; i++) {
          x = ex9.chan.receive();
          if (x instanceof BigInteger) {
             v = (BigInteger)x;
          } else { 
            System.out.println("Non BigInteger received." + x);
          }
          ex9.probe();
    }

    synchronized (ex9.prn) { 
       System.out.println("         v  = " + v);
       System.out.println("         cd = " + l);
    }

  }
}


public class ex9 {
  
  /*parameters */
  public static final int t = 10, m = 50, w = 200;

  /* channel */
  public static Channel chan;

  /* print serialization */
  public static Object prn;

  public static int p = 100; 
 
  public static void main(String[] args) throws InterruptedException {

    if (args.length == 1) { 
       try { p = Integer.parseInt(args[0]); } 
       catch (NumberFormatException e) { } 
    } 

    /* init channel */
    chan = new Channel(m);
 
    prn = new Object(); 

    /* con statement */
    Thread pt[] = new Thread[t]; 
    for (int i = 0; i<t; i++) { 
        pt[i] = new Thread(new ex9prod(w/t));
        pt[i].start();
    }
    Thread ct[] = new Thread[t]; 
    for (int i = 0; i<t; i++) { 
        ct[i] = new Thread(new ex9cons(w/t));
        ct[i].start();
    }
    System.out.println("started");
    for (int i = 0; i<t; i++) { pt[i].join(); }
    for (int i = 0; i<t; i++) { ct[i].join(); }

    System.out.println("termination");

  }
 
  public static void probe() { 
    Sleep.sleep(p);
  }

}




