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