// JavaThreadTutorial.java - showing some threading concepts in Java by RJM Programming
import java.util.Date;
public class JavaThreadTutorial extends Thread {
 private int lastsforever;
 public JavaThreadTutorial(int value) {  lastsforever = value; }
 private synchronized void updateforevervar() {  lastsforever++; }

 public void run() {
  int localtorunfunc;
  Thread thread = Thread.currentThread();
  System.out.println("run() is being run by " + thread.getName() + " at " + new Date());
  localtorunfunc = lastsforever;
  updateforevervar();
  System.out.println("localtorunfunc = " + localtorunfunc + ", lastsforever = " + lastsforever);
 }

 public static void main(String[] args) {
  int i=0,j,k;
  boolean orderly = false;
  JavaThreadTutorial jtt[] = new JavaThreadTutorial[8];
  
  for (k=0; k < 8; k+=4) {  // For two sets of 4 x thread calls  first !orderly, second orderly
  
   // When orderly .join() calls for each looping ensure thread goes its full term before another starts
   System.out.println("----------------------- orderly=" + orderly + "------------------------");
   for (i=400, j=k; i<=700; i += 100, j++) {
    jtt[j] = new JavaThreadTutorial(i);
    System.out.println("pre jtt[" + j + "].start");
    jtt[j].start();
    System.out.println("post jtt[" + j + "].start");
    
    if (orderly) { // .join() here when orderly ensures 1 thread runs to completion before next starts     
     try {
      System.out.println("pre jtt[" + j + "].join");
      jtt[j].join();
      System.out.println("post jtt[" + j + "].join");
     } catch (InterruptedException e) { System.out.println("posterr jtt[" + j + "].join"); }
    }
   }
      
   for (j=0; j<4; j++) { // This clears up all outstanding threads in this set of 4 no matter what
    try {
      System.out.println("pre jtt[" + j + "].join");
      jtt[j].join();
      System.out.println("post jtt[" + j + "].join");
    } catch (InterruptedException e) {  System.out.println("posterr jtt[" + j + "].join"); }
   }
   
   orderly = !orderly;  // Toggle the orderly variable
  }
 }
}
