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();
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();
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();
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 
137     private static int count = 0;
138 
SleepyThread(SleepyThread other)139     SleepyThread(SleepyThread other) {
140         mOther = other;
141         mWaitOnMe = new Integer[] { 1, 2 };
142 
143         setName("thread#" + count);
144         count++;
145     }
146 
run()147     public void run() {
148         System.out.println("SleepyThread.run starting");
149 
150         if (false) {
151             ThreadDeathHandler threadHandler =
152                 new ThreadDeathHandler("SYNC THREAD");
153             Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
154             throw new NullPointerException("die");
155         }
156 
157         if (mOther == null) {
158             boolean intr = false;
159 
160             try {
161                 synchronized (mWaitOnMe) {
162                     mWaitOnMe.wait(9000);
163                 }
164             } catch (InterruptedException ie) {
165                 // Expecting this; interrupted should be false.
166                 System.out.println(Thread.currentThread().getName() +
167                         " interrupted, flag=" + Thread.interrupted());
168                 intr = true;
169             } catch (Exception ex) {
170                 ex.printStackTrace();
171             }
172 
173             if (!intr)
174                 System.out.println("NOT INTERRUPTED");
175         } else {
176             try {
177                 Thread.sleep(2000);
178             } catch (InterruptedException ie) {
179                 System.out.println("PESKY INTERRUPTED?");
180             }
181 
182             System.out.println("interrupting other (isAlive="
183                 + mOther.isAlive() + ")");
184             mOther.interrupt();
185         }
186     }
187 }
188