// RunThread.java  four computational threads for four processors

import java.awt.*;
import java.awt.event.*;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class RunThread
{
  int pos = 0; // window location
  int cfctr = 400000; // computation iterations for delay
  long t_start;  // for System.currentTimeMillis
  double t_end;

  RunThread()
  {
    System.out.println("RunThread starting");
    t_start = System.currentTimeMillis();

    new MyThread("one", Color.red).start();
    new MyThread("two", Color.green).start();
    new MyThread("three", Color.blue).start();
    new MyThread("four", Color.black).start();
    t_end = (System.currentTimeMillis()-t_start)/1000.0;
    System.out.println("RunThread constructor ending "+t_end+" seconds");
  } // end RunThread constructor
  
  class MyThread extends Thread
  {
    String id;
    Graphics g;
    Color c;
    
    MyThread(String who, Color col)
    {
      id = who;
      // initiate window
      Frame f = new Frame();
      f.setTitle("RunThreads "+who);
      f.setLocation(300*pos,50);
      pos++;
      f.setSize(300,300);
      f.setBackground(Color.white);
      f.setForeground(Color.black);
      f.setVisible(true);
      g = f.getGraphics();
      c = col;
    } // end MyThread constructor
    
    public void run()
    {
      double x, y, z, th_end, tb_end;
      long th_start, tb_start;
      ThreadMXBean tb = ManagementFactory.getThreadMXBean();

      th_start = System.currentTimeMillis(); // wall time
      tb_start = tb.getCurrentThreadCpuTime();

      try
      {
        for(int i=0; i<13; i++)
        {
          z = 0.001;
          System.out.println(id+" #"+i+" z="+z);
          g.setColor(c);
          g.fillOval(20+20*i,30+20*i,10,10);
          sleep(1); // this releases so other threads can run
          for(int j=0; j<cfctr; j++) // waste time
	  {
	      y = Math.exp(Math.sin(z)-Math.cos(z));
              x = Math.sqrt(Math.sqrt(y));
              z = z + x;
	  }
          if(i==10)
	  {
            th_end = (System.currentTimeMillis()-t_start)/1000.0;
            System.out.println("thread "+id+" at 10 at "+th_end+" seconds wall");
            tb_end = tb.getCurrentThreadCpuTime()-tb_start;
            System.out.println("thread "+id+" at 10 at "+tb_end+" seconds CPU");
	  }
        }
      }
      catch(InterruptedException e)
      {
      }
      th_end = (System.currentTimeMillis()-th_start)/1000.0;
      System.out.println("thread "+id+" ends at "+th_end+" seconds wall");
      tb_end = tb.getCurrentThreadCpuTime()-tb_start;
      System.out.println("thread "+id+" ends at "+tb_end+" seconds CPU");
      System.exit(0);
    } // end Run
  } // end class MyThread
  
  static public void main(String[] args)
  {
    new RunThread();
    System.out.println("RunThread main ending");
  } // end main
} // end class RunThread

