/* * 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(); } } }