1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Test synchronization primitives.
19  *
20  * TODO: this should be re-written to be a little more rigorous and/or
21  * useful.  Also, the ThreadDeathHandler stuff should be exposed or
22  * split out.
23  */
24 public class Main {
main(String[] args)25     public static void main(String[] args) {
26         System.out.println("Sleep Test");
27         sleepTest();
28 
29         System.out.println("\nCount Test");
30         countTest();
31 
32         System.out.println("\nInterrupt Test");
33         interruptTest();
34     }
35 
sleepTest()36     static void sleepTest() {
37         System.out.println("GOING");
38         try {
39             Thread.sleep(1000);
40         } catch (InterruptedException ie) {
41             System.out.println("INTERRUPT!");
42             ie.printStackTrace(System.out);
43         }
44         System.out.println("GONE");
45     }
46 
countTest()47     static void countTest() {
48         CpuThread one, two;
49 
50         one = new CpuThread(1);
51         two = new CpuThread(2);
52 
53         synchronized (one) {
54             one.start();
55             try {
56                 one.wait();
57             } catch (InterruptedException ie) {
58                 System.out.println("INTERRUPT!");
59                 ie.printStackTrace(System.out);
60             }
61         }
62 
63         two.start();
64 
65         //System.out.println("main: off and running");
66 
67         try {
68             one.join();
69             two.join();
70         } catch (InterruptedException ie) {
71             System.out.println("INTERRUPT!");
72             ie.printStackTrace(System.out);
73         }
74         System.out.println("main: all done");
75     }
76 
interruptTest()77     static void interruptTest() {
78         SleepyThread sleepy, pesky;
79 
80         sleepy = new SleepyThread(null);
81         pesky = new SleepyThread(sleepy);
82 
83         sleepy.setPriority(4);
84         sleepy.start();
85         pesky.start();
86         pesky.setPriority(3);
87     }
88 }
89 
90 class CpuThread extends Thread {
91     static Object mSyncable = new Object();
92     static int mCount = 0;
93     int mNumber;
94 
CpuThread(int num)95     CpuThread(int num) {
96         super("CpuThread " + num);
97         mNumber = num;
98     }
99 
run()100     public void run() {
101         //System.out.print("thread running -- ");
102         //System.out.println(Thread.currentThread().getName());
103 
104         synchronized (mSyncable) {
105             synchronized (this) {
106                 this.notify();
107             }
108             for (int i = 0; i < 10; i++) {
109                 output(mNumber);
110             }
111 
112             System.out.print("Final result: ");
113             System.out.println(mCount);
114         }
115     }
116 
output(int num)117     void output(int num) {
118         int count = mCount;
119 
120         System.out.print("going: ");
121         System.out.println(num);
122 
123         /* burn CPU; adjust end value so we exceed scheduler quantum */
124         for (int j = 0; j < 5000; j++) {
125             ;
126         }
127 
128         count++;
129         mCount = count;
130     }
131 }
132 
133 class SleepyThread extends Thread {
134     private SleepyThread mOther;
135     private Integer[] mWaitOnMe;      // any type of object will do
136     private volatile boolean otherDone;
137 
138     private static int count = 0;
139 
SleepyThread(SleepyThread other)140     SleepyThread(SleepyThread other) {
141         mOther = other;
142         otherDone = false;
143         mWaitOnMe = new Integer[] { 1, 2 };
144 
145         setName("thread#" + count);
146         count++;
147     }
148 
run()149     public void run() {
150         System.out.println("SleepyThread.run starting");
151 
152         if (false) {
153             ThreadDeathHandler threadHandler =
154                 new ThreadDeathHandler("SYNC THREAD");
155             Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
156             throw new NullPointerException("die");
157         }
158 
159         if (mOther == null) {
160             boolean intr = false;
161 
162             try {
163               do {
164                 synchronized (mWaitOnMe) {
165                     mWaitOnMe.wait(9000);
166                 }
167               } while (!otherDone);
168             } catch (InterruptedException ie) {
169                 // Expecting this; interrupted should be false.
170                 System.out.println(Thread.currentThread().getName() +
171                         " interrupted, flag=" + Thread.interrupted());
172                 intr = true;
173             } catch (Exception ex) {
174                 ex.printStackTrace(System.out);
175             }
176 
177             if (!intr)
178                 System.out.println("NOT INTERRUPTED");
179         } else {
180             try {
181                 Thread.sleep(2000);
182             } catch (InterruptedException ie) {
183                 System.out.println("PESKY INTERRUPTED?");
184             }
185 
186             System.out.println("interrupting other (isAlive="
187                 + mOther.isAlive() + ")");
188             mOther.interrupt();
189             mOther.otherDone = true;
190         }
191     }
192 }
193