content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /**
   * Test synchronization primitives.
   *
   * TODO: this should be re-written to be a little more rigorous and/or
   * useful.  Also, the ThreadDeathHandler stuff should be exposed or
   * split out.
   */
  public class Main {
      public static void main(String[] args) {
          System.out.println("Sleep Test");
          sleepTest();
  
          System.out.println("\nCount Test");
          countTest();
  
          System.out.println("\nInterrupt Test");
          interruptTest();
      }
  
      static void sleepTest() {
          System.out.println("GOING");
          try {
              Thread.sleep(1000);
          } catch (InterruptedException ie) {
              System.out.println("INTERRUPT!");
              ie.printStackTrace();
          }
          System.out.println("GONE");
      }
  
      static void countTest() {
          CpuThread one, two;
  
          one = new CpuThread(1);
          two = new CpuThread(2);
  
          synchronized (one) {
              one.start();
              try {
                  one.wait();
              } catch (InterruptedException ie) {
                  System.out.println("INTERRUPT!");
                  ie.printStackTrace();
              }
          }
  
          two.start();
  
          //System.out.println("main: off and running");
  
          try {
              one.join();
              two.join();
          } catch (InterruptedException ie) {
              System.out.println("INTERRUPT!");
              ie.printStackTrace();
          }
          System.out.println("main: all done");
      }
  
      static void interruptTest() {
          SleepyThread sleepy, pesky;
  
          sleepy = new SleepyThread(null);
          pesky = new SleepyThread(sleepy);
  
          sleepy.setPriority(4);
          sleepy.start();
          pesky.start();
          pesky.setPriority(3);
      }
  }
  
  class CpuThread extends Thread {
      static Object mSyncable = new Object();
      static int mCount = 0;
      int mNumber;
  
      CpuThread(int num) {
          super("CpuThread " + num);
          mNumber = num;
      }
  
      public void run() {
          //System.out.print("thread running -- ");
          //System.out.println(Thread.currentThread().getName());
  
          synchronized (mSyncable) {
              synchronized (this) {
                  this.notify();
              }
              for (int i = 0; i < 10; i++) {
                  output(mNumber);
              }
  
              System.out.print("Final result: ");
              System.out.println(mCount);
          }
      }
  
      void output(int num) {
          int count = mCount;
  
          System.out.print("going: ");
          System.out.println(num);
  
          /* burn CPU; adjust end value so we exceed scheduler quantum */
          for (int j = 0; j < 5000; j++) {
              ;
          }
  
          count++;
          mCount = count;
      }
  }
  
  class SleepyThread extends Thread {
      private SleepyThread mOther;
      private Integer[] mWaitOnMe;      // any type of object will do
  
      private static int count = 0;
  
      SleepyThread(SleepyThread other) {
          mOther = other;
          mWaitOnMe = new Integer[] { 1, 2 };
  
          setName("thread#" + count);
          count++;
      }
  
      public void run() {
          System.out.println("SleepyThread.run starting");
  
          if (false) {
              ThreadDeathHandler threadHandler =
                  new ThreadDeathHandler("SYNC THREAD");
              Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
              throw new NullPointerException("die");
          }
  
          if (mOther == null) {
              boolean intr = false;
  
              try {
                  synchronized (mWaitOnMe) {
                      mWaitOnMe.wait(9000);
                  }
              } catch (InterruptedException ie) {
                  // Expecting this; interrupted should be false.
                  System.out.println(Thread.currentThread().getName() +
                          " interrupted, flag=" + Thread.interrupted());
                  intr = true;
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
  
              if (!intr)
                  System.out.println("NOT INTERRUPTED");
          } else {
              try {
                  Thread.sleep(2000);
              } catch (InterruptedException ie) {
                  System.out.println("PESKY INTERRUPTED?");
              }
  
              System.out.println("interrupting other (isAlive="
                  + mOther.isAlive() + ")");
              mOther.interrupt();
          }
      }
  }
  