1. class TickTock {
  2.     String state;
  3.     boolean virginity=true;
  4.  
  5.     synchronized void tick(boolean running) {
  6.         if (virginity) virginity=false;
  7.  
  8.         if (!running) {
  9.             state = "ticked";
  10.             notify();
  11.             return;
  12.         }
  13.  
  14.         System.out.print("Tick ");
  15.  
  16.         state = "ticked";
  17.        
  18.         notify();
  19.         try {
  20.             while(!state.equals("tocked"))
  21.                 wait();
  22.         } catch (InterruptedException exc) {
  23.             System.out.println("Thread interrupted.");
  24.         }
  25.     }
  26.  
  27.     synchronized void tock(boolean running) {
  28.         if (virginity) {
  29.             try {
  30.                 wait();
  31.             } catch (InterruptedException exc) {
  32.                 System.out.println("Thread interrupted.");
  33.             }
  34.         }
  35.  
  36.         if (!running) {
  37.             state = "tocked";
  38.             notify();
  39.             return;
  40.         }
  41.  
  42.         System.out.print("Tock ");
  43.        
  44.         state = "tocked";
  45.  
  46.         notify();
  47.         try {
  48.             while(!state.equals("ticked"))
  49.                 wait();
  50.         } catch (InterruptedException exc) {
  51.             System.out.println("Thread interrupted.");
  52.         }
  53.     }
  54. }
  55.  
  56. class MyThread implements Runnable {
  57.     Thread thrd;
  58.     TickTock ttOb;
  59.  
  60.     MyThread(String name, TickTock tt) {
  61.         thrd = new Thread(this, name);
  62.         ttOb = tt;
  63.         thrd.start();
  64.     }
  65.    
  66.     public void run() {
  67.         if (thrd.getName().compareTo("Tick") == 0) {
  68.             for (int i=0; i<5; i++) ttOb.tick(true);
  69.             ttOb.tick(false);
  70.         } else {
  71.             for (int i=0; i<5; i++) ttOb.tock(true);
  72.             ttOb.tock(false);
  73.         }
  74.     }
  75. }
  76.  
  77. class ThreadCom {
  78.     public static void main(String args[]) {
  79.         TickTock tt = new TickTock();
  80.         MyThread mt1 = new MyThread("Tick", tt);
  81.         MyThread mt2 = new MyThread("Tock", tt);
  82.  
  83.         try {
  84.             mt1.thrd.join();
  85.             mt2.thrd.join();
  86.         } catch (InterruptedException exc) {
  87.             System.out.println("Main thread interrupted.");
  88.         }
  89.         System.out.println();
  90.     }
  91. }