12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2006 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Test synchronization primitives.
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * TODO: this should be re-written to be a little more rigorous and/or
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * useful.  Also, the ThreadDeathHandler stuff should be exposed or
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * split out.
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main {
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main(String[] args) {
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("Sleep Test");
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        sleepTest();
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("\nCount Test");
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        countTest();
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("\nInterrupt Test");
335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        interruptTest();
345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void sleepTest() {
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("GOING");
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Thread.sleep(1000);
40741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        } catch (InterruptedException ie) {
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("INTERRUPT!");
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ie.printStackTrace();
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("GONE");
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void countTest() {
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        CpuThread one, two;
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        one = new CpuThread(1);
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        two = new CpuThread(2);
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
538d9044bb4039bfd46b20edce4cff929906e492c6Alex Light        synchronized (one) {
548d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            one.start();
558d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            try {
568d9044bb4039bfd46b20edce4cff929906e492c6Alex Light                one.wait();
578d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            } catch (InterruptedException ie) {
588d9044bb4039bfd46b20edce4cff929906e492c6Alex Light                System.out.println("INTERRUPT!");
598d9044bb4039bfd46b20edce4cff929906e492c6Alex Light                ie.printStackTrace();
608d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            }
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
63741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        two.start();
64741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("main: off and running");
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            one.join();
695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            two.join();
70741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        } catch (InterruptedException ie) {
715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("INTERRUPT!");
725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ie.printStackTrace();
735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("main: all done");
755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void interruptTest() {
785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        SleepyThread sleepy, pesky;
795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        sleepy = new SleepyThread(null);
815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        pesky = new SleepyThread(sleepy);
825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        sleepy.setPriority(4);
845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        sleepy.start();
855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        pesky.start();
865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        pesky.setPriority(3);
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass CpuThread extends Thread {
915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static Object mSyncable = new Object();
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static int mCount = 0;
935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    int mNumber;
945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    CpuThread(int num) {
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        super("CpuThread " + num);
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        mNumber = num;
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void run() {
1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.print("thread running -- ");
1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println(Thread.currentThread().getName());
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
104741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        synchronized (mSyncable) {
1058d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            synchronized (this) {
1068d9044bb4039bfd46b20edce4cff929906e492c6Alex Light                this.notify();
1078d9044bb4039bfd46b20edce4cff929906e492c6Alex Light            }
108741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            for (int i = 0; i < 10; i++) {
109741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes                output(mNumber);
110741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            }
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
112741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            System.out.print("Final result: ");
113741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            System.out.println(mCount);
114741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        }
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    void output(int num) {
118741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        int count = mCount;
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
120741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        System.out.print("going: ");
121741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        System.out.println(num);
1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
123741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        /* burn CPU; adjust end value so we exceed scheduler quantum */
124741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        for (int j = 0; j < 5000; j++) {
125741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            ;
1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
127741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes
128741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        count++;
129741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes        mCount = count;
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass SleepyThread extends Thread {
1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private SleepyThread mOther;
1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private Integer[] mWaitOnMe;      // any type of object will do
1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static int count = 0;
1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    SleepyThread(SleepyThread other) {
1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        mOther = other;
1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        mWaitOnMe = new Integer[] { 1, 2 };
1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        setName("thread#" + count);
1445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        count++;
1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void run() {
1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("SleepyThread.run starting");
1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (false) {
1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ThreadDeathHandler threadHandler =
1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                new ThreadDeathHandler("SYNC THREAD");
1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new NullPointerException("die");
1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (mOther == null) {
1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            boolean intr = false;
1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            try {
1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                synchronized (mWaitOnMe) {
1625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    mWaitOnMe.wait(9000);
1635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                }
164741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            } catch (InterruptedException ie) {
1655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                // Expecting this; interrupted should be false.
1665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println(Thread.currentThread().getName() +
1675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                        " interrupted, flag=" + Thread.interrupted());
1685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                intr = true;
169741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            } catch (Exception ex) {
1705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                ex.printStackTrace();
1715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (!intr)
1745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("NOT INTERRUPTED");
1755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } else {
1765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            try {
1775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                Thread.sleep(2000);
178741b5b7ef4c7fd4a786364bbf60d515489caff47Elliott Hughes            } catch (InterruptedException ie) {
1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("PESKY INTERRUPTED?");
1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("interrupting other (isAlive="
1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                + mOther.isAlive() + ")");
1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            mOther.interrupt();
1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
188