| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| package java.lang; |
| |
| import junit.framework.TestCase; |
| |
| import java.util.Map; |
| import java.util.Set; |
| import org.apache.harmony.test.ReversibleSecurityManager; |
| |
| /** |
| * This class provides an implementation of J2SE v. 1.5 API Specification of |
| * unit.java.lang.ThreadTest class. |
| */ |
| public class ThreadTest extends TestCase { |
| |
| private static final String INTERRUPTED_MESSAGE = |
| "thread has been unexpectedly interrupted"; |
| |
| // max time interval to wait for some events in ms |
| private static final long waitDuration = 60000; |
| |
| // waiting time for some event |
| private long waitTime = 0; |
| |
| private boolean expired; |
| private SecurityManager sm = null; |
| |
| private enum Action {WAIT, SLEEP, JOIN} |
| |
| private class RunProject extends Thread { |
| private Team team; |
| RunProject(Team t) { |
| this.team = t; |
| } |
| |
| public void run () { |
| team.work(); |
| } |
| } |
| |
| private class Team { |
| public volatile int i = 0; |
| volatile boolean stopProject = false; |
| |
| public synchronized void work() { |
| while (!stopProject) { |
| i++; |
| } |
| } |
| public void stopWork() { |
| stopProject = true; |
| } |
| } |
| |
| private class TestThread extends Thread { |
| |
| public InterruptedException e = null; |
| |
| public void run() { |
| try { |
| synchronized (this) { |
| this.notify(); |
| this.wait(); |
| } |
| } catch(InterruptedException e) { |
| this.e = e; |
| } |
| } |
| } |
| |
| static class ThreadRunning extends Thread { |
| volatile boolean stopWork = false; |
| long startTime; |
| public volatile int i = 0; |
| |
| ThreadRunning() { |
| super(); |
| } |
| |
| ThreadRunning(String name) { |
| super(name); |
| } |
| |
| ThreadRunning(Runnable target, String name) { |
| super(target, name); |
| } |
| |
| ThreadRunning(ThreadGroup g, String name) { |
| super(g, name); |
| } |
| |
| ThreadRunning(ThreadGroup g, Runnable target) { |
| super(g, target); |
| } |
| |
| ThreadRunning(ThreadGroup g, Runnable target, String name) { |
| super(g, target, name); |
| } |
| |
| public void run () { |
| startTime = System.currentTimeMillis(); |
| while (!stopWork) { |
| i++; |
| } |
| } |
| |
| public long getStartTime() { |
| return startTime; |
| } |
| } |
| |
| private class ThreadWaiting extends Thread { |
| public volatile boolean started = false; |
| private long millis; |
| private int nanos; |
| private Action action; |
| private boolean exceptionReceived = false; |
| private long startTime; |
| private long endTime; |
| private Object lock; |
| |
| ThreadWaiting(Action action, long millis, int nanos, Object lock) { |
| this.millis = millis; |
| this.nanos = nanos; |
| this.action = action; |
| this.lock = lock; |
| } |
| |
| public void run () { |
| switch (action) { |
| case WAIT: |
| synchronized (lock) { |
| this.started = true; |
| lock.notify(); |
| } |
| synchronized (this) { |
| try { |
| this.wait(millis, nanos); |
| } catch (InterruptedException e) { |
| exceptionReceived = true; |
| } |
| } |
| case SLEEP: |
| try { |
| synchronized (lock) { |
| started = true; |
| lock.notify(); |
| } |
| this.startTime = System.currentTimeMillis(); |
| Thread.sleep(millis, nanos); |
| this.endTime = System.currentTimeMillis(); |
| } catch (InterruptedException e) { |
| exceptionReceived = true; |
| } |
| case JOIN: |
| try { |
| synchronized (lock) { |
| started = true; |
| lock.notify(); |
| } |
| this.join(millis, nanos); |
| } catch (InterruptedException e) { |
| exceptionReceived = true; |
| } |
| } |
| } |
| |
| public long getStartTime() { |
| return startTime; |
| } |
| |
| public long getEndTime() { |
| return endTime; |
| } |
| } |
| |
| private class ThreadRunningAnotherThread extends Thread { |
| int field = 0; |
| volatile boolean stop = false; |
| boolean childIsDaemon = false; |
| Thread curThread = null; |
| |
| public ThreadRunningAnotherThread() { |
| super(); |
| } |
| |
| public ThreadRunningAnotherThread(String name) { |
| super(name); |
| } |
| |
| public void run () { |
| Thread child = new Thread(); |
| curThread = Thread.currentThread(); |
| childIsDaemon = child.isDaemon(); |
| while (!stop) { |
| field++; |
| } |
| } |
| } |
| |
| private static class ThreadYielding extends Thread { |
| private int item; |
| public static final int dim = 200; |
| public static int list[] = new int[dim]; |
| private static int index = 0; |
| |
| public ThreadYielding(int item) { |
| this.item = item; |
| } |
| |
| private static synchronized int getNextIndex() { |
| return index++; |
| } |
| |
| public synchronized void setItem() { |
| list[getNextIndex()] = this.item; |
| } |
| |
| public void run () { |
| for (int i = 0; i < dim / 2; i++) { |
| setItem(); |
| Thread.yield(); |
| } |
| } |
| } |
| |
| class Square implements Runnable { |
| volatile boolean stop = false; |
| boolean once; |
| int number; |
| int squaredNumber; |
| |
| Square(int number) { |
| this(number, false); |
| } |
| |
| Square(int number, boolean once) { |
| this.number = number; |
| this.once = once; |
| } |
| |
| public void run() { |
| while (!stop) { |
| squaredNumber = number * number; |
| if (once) { |
| break; |
| } |
| } |
| } |
| } |
| |
| /** |
| * Sleep for "interval" ms |
| * @return true if waitTime is up |
| */ |
| private boolean doSleep(int interval) { |
| try { |
| Thread.sleep(interval); |
| } catch (InterruptedException e) { |
| fail("unexpected InterruptedException while sleeping"); |
| } |
| waitTime -= interval; |
| return waitTime <= 0; |
| } |
| |
| /** |
| * Verify that the toString() method displays the thread's name, |
| * priority and thread group. |
| */ |
| public void testToString() { |
| Thread t = new Thread(); |
| String info = t.toString(); |
| String name = t.getName(); |
| assertTrue("thread's name is not displayed", info.indexOf(name) >= 0); |
| String stringPriority = new Integer(t.getPriority()).toString(); |
| assertTrue("thread's priority is not displayed", |
| info.indexOf("," + stringPriority + ",") > 0); |
| String groupName = t.getThreadGroup().getName(); |
| assertTrue("thread's group is not displayed", info.indexOf(groupName) > 0); |
| } |
| |
| /** |
| * Thread() |
| */ |
| public void testThread() { |
| Thread t = new Thread(); |
| assertTrue("incorrect thread name", |
| t.toString().indexOf("Thread-") >= 0); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| } |
| |
| /** |
| * Verify that a thread created by a daemon thread is daemon |
| */ |
| public void testThread_Daemon() { |
| ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); |
| t.setDaemon(true); |
| t.start(); |
| t.stop = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| assertTrue("the child thread of a daemon thread is non-daemon", |
| t.childIsDaemon); |
| } |
| |
| /** |
| * Verify that a thread created by a non-daemon thread is not daemon |
| */ |
| public void testThread_NotDaemon() { |
| ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); |
| t.setDaemon(false); |
| t.start(); |
| t.stop = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| assertFalse("the child thread of a non-daemon thread is daemon", |
| t.childIsDaemon); |
| } |
| |
| /** |
| * Thread(Runnable) |
| */ |
| public void testThreadRunnable() { |
| Square s = new Square(25); |
| Thread t = new Thread(s); |
| t.start(); |
| waitTime = waitDuration; |
| while (s.squaredNumber == 0 && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| s.stop = true; |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| /** |
| * Thread(Runnable, String) |
| */ |
| public void testThreadRunnableString() { |
| Square s = new Square(25); |
| String name = "squaring"; |
| Thread t = new Thread(s, name); |
| t.start(); |
| waitTime = waitDuration; |
| while (s.squaredNumber == 0 && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorrect thread name", name, t.getName()); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| s.stop = true; |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| /** |
| * Thread(Runnable, String) |
| */ |
| public void testThreadRunnableString_NullNotNull() { |
| String name = "newThread"; |
| ThreadRunning t = new ThreadRunning((Runnable) null, name); |
| assertEquals("incorrect thread name", name, t.getName()); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| t.start(); |
| // thread's run() method should be called if Runnable==null |
| waitTime = waitDuration; |
| while (t.i == 0 && !(expired = doSleep(10))) { |
| } |
| t.stopWork = true; |
| assertTrue("thread's run() method has not started", t.i != 0); |
| } |
| |
| /** |
| * Thread(String) |
| */ |
| public void testThreadString() { |
| String name = "threadString"; |
| Thread t = new Thread(name); |
| assertTrue("incorrect thread name", |
| t.toString().indexOf(name) >= 0); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| } |
| |
| /** |
| * Verify creating a thread with the null name. |
| * NullPointerException should be thrown. |
| */ |
| public void testThreadStringNull() { |
| String threadName = null; |
| try { |
| new Thread(threadName); |
| fail ("NullPointerException should be thrown when creating " |
| + "a thread with null name"); |
| } catch (NullPointerException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable) |
| */ |
| public void testThreadThreadGroupRunnable() { |
| Square s = new Square(25); |
| ThreadGroup tg = new ThreadGroup("newGroup"); |
| Thread t = new Thread(tg, s); |
| t.start(); |
| waitTime = waitDuration; |
| while (s.squaredNumber == 0 && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); |
| assertSame("incorrect thread group", tg, t.getThreadGroup()); |
| s.stop = true; |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable) where both arguments are null |
| */ |
| public void testThreadThreadGroupRunnable_NullNull() { |
| ThreadRunning t = new ThreadRunning((ThreadGroup) null, (Runnable) null); |
| assertEquals("incorrect thread name", 0, t.getName().indexOf("Thread-")); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| t.start(); |
| // thread's run() method should be called if Runnable==null |
| waitTime = waitDuration; |
| while (t.i == 0 && !(expired = doSleep(10))) { |
| } |
| t.stopWork = true; |
| assertTrue("thread's run() method has not started", t.i != 0); |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String) |
| */ |
| public void testThreadThreadGroupRunnableString() { |
| ThreadGroup tg = new ThreadGroup("newGroup"); |
| String name = "t1"; |
| Square s = new Square(25); |
| Thread t = new Thread(tg, s, name); |
| t.start(); |
| waitTime = waitDuration; |
| while (s.squaredNumber == 0 && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorrect thread name", 0, t.getName().indexOf(name)); |
| assertSame("incorrect thread group", tg, t.getThreadGroup()); |
| s.stop = true; |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String) where all arguments are null |
| */ |
| public void testThreadThreadGroupRunnableString_NullNullNull() { |
| try { |
| new Thread(null, null, null); |
| fail("NullPointerException has not been thrown"); |
| } catch (NullPointerException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String) where both |
| * ThreadGroup and Runnable are null |
| */ |
| public void testThreadThreadGroupRunnableString_NullNullNotNull() { |
| String name = "t1"; |
| ThreadRunning t1 = new ThreadRunning(null, null, name); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t1.getThreadGroup()); |
| t1.start(); |
| // thread's run() method should be called if Runnable==null |
| waitTime = waitDuration; |
| while (t1.i == 0 && !(expired = doSleep(10))) { |
| } |
| t1.stopWork = true; |
| assertTrue("thread's run() method has not started", t1.i != 0); |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String) where ThreadGroup is null |
| */ |
| public void testThreadThreadGroupRunnableString_NullNotNullNotNull() { |
| String name = "t1"; |
| Square s = new Square(25); |
| Thread t = new Thread(null, s, name); |
| t.start(); |
| waitTime = waitDuration; |
| while (s.squaredNumber == 0 && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorrect thread name", 0, t.getName().indexOf(name)); |
| assertSame("incorrect thread group", |
| Thread.currentThread().getThreadGroup(), t.getThreadGroup()); |
| s.stop = true; |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String, long) |
| */ |
| public void testThreadThreadGroupRunnableStringlong() { |
| ThreadGroup tg = new ThreadGroup("newGroup"); |
| String name = "t1"; |
| Square s = new Square(25); |
| Thread t = new Thread(tg, s, name, 0); |
| t.start(); |
| waitTime = waitDuration; |
| StackTraceElement ste[] = t.getStackTrace(); |
| while (ste.length == 0 && !(expired = doSleep(10))) { |
| ste = t.getStackTrace(); |
| } |
| s.stop = true; |
| if (expired) { |
| fail("stack dump of thread t1 is empty"); |
| } |
| } |
| |
| /** |
| * Thread(ThreadGroup, Runnable, String, long) |
| */ |
| public void testThreadThreadGroupRunnableStringlong_Long_MAX_VALUE() { |
| ThreadGroup tg = new ThreadGroup("newGroup"); |
| String name = "t1"; |
| Square s = new Square(25); |
| StackTraceElement ste[] = null; |
| try { |
| Thread t; |
| try { |
| t = new Thread(tg, s, name, Long.MAX_VALUE); |
| } catch (OutOfMemoryError e) { |
| // fall back to default stack size if can't allocate |
| // Long.MAX_VALUE bytes for stack |
| t = new Thread(tg, s, name, 0); |
| } |
| t.start(); |
| waitTime = waitDuration; |
| ste = t.getStackTrace(); |
| while (ste.length == 0 && !(expired = doSleep(10))) { |
| ste = t.getStackTrace(); |
| } |
| s.stop = true; |
| if (expired) { |
| fail("stack dump of thread t1 is empty"); |
| } |
| } catch (OutOfMemoryError er) { |
| fail("OutOfMemoryError when stack size is Long.MAX_VALUE"); |
| } |
| } |
| |
| /** |
| * Thread(ThreadGroup, String) |
| */ |
| public void testThreadThreadGroupString() { |
| String name = "newThread"; |
| ThreadGroup tg = new ThreadGroup("newGroup"); |
| Thread t = new Thread(tg, name); |
| assertEquals("incorrect thread name", name, t.getName()); |
| assertSame("incorrect thread group", tg, t.getThreadGroup()); |
| } |
| |
| /** |
| * Get active threads count; should be > 0 |
| */ |
| public void testActiveCount() { |
| int activeCount = Thread.activeCount(); |
| assertTrue("The active threads count must be >0.", activeCount > 0); |
| } |
| |
| /** |
| * Verify currentThread() |
| */ |
| public void testCurrentThread() { |
| String name = "runThread"; |
| ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(name); |
| t.start(); |
| waitTime = waitDuration; |
| while (t.curThread == null && !(expired = doSleep(10))) { |
| } |
| assertEquals("incorect current thread name", name, t.curThread.getName()); |
| t.stop = true; |
| } |
| |
| /** |
| * Verify currentThread() |
| */ |
| public void testCurrentThread_Main() { |
| String name = "ain"; |
| Thread t = Thread.currentThread(); |
| assertTrue("incorect current thread name", t.getName().indexOf(name) > 0); |
| } |
| |
| public void testEnumerate() { |
| ThreadRunning t1 = new ThreadRunning("ttt1"); |
| t1.start(); |
| ThreadRunning t2 = new ThreadRunning("ttt2"); |
| t2.start(); |
| ThreadGroup tg1 = new ThreadGroup("tg1"); |
| ThreadRunning t11 = new ThreadRunning(tg1, "ttt11"); |
| t11.start(); |
| ThreadRunning t12 = new ThreadRunning(tg1, "ttt12"); |
| t12.start(); |
| ThreadGroup tg12 = new ThreadGroup(tg1, "tg12"); |
| ThreadRunning t121 = new ThreadRunning(tg12, "ttt121"); |
| t121.start(); |
| ThreadRunning t122 = new ThreadRunning(tg12, "ttt122"); |
| t122.start(); |
| // estimate dimension as 6 created threads |
| // plus 10 for some other threads |
| int estimateLength = 16; |
| Thread list[]; |
| int count; |
| while (true) { |
| list = new Thread[estimateLength]; |
| count = Thread.enumerate(list); |
| if (count == estimateLength) { |
| estimateLength *= 2; |
| } else { |
| break; |
| } |
| } |
| int enumerateCount = 0; |
| for (int i = 0; i < count; i++) { |
| if (list[i].toString().indexOf("ttt") > 0) { |
| enumerateCount++; |
| } |
| } |
| t1.stopWork = true; |
| t2.stopWork = true; |
| t11.stopWork = true; |
| t12.stopWork = true; |
| t121.stopWork = true; |
| t122.stopWork = true; |
| assertEquals("some threads are missed", 6, enumerateCount); |
| } |
| |
| /** |
| * Test for holdsLock(Object obj) |
| */ |
| public void testHoldsLock_False() { |
| Object lock = new Object(); |
| assertFalse("lock should not be held", Thread.holdsLock(lock)); |
| } |
| |
| /** |
| * Test for holdsLock(Object obj) |
| */ |
| public void testHoldsLock_True() { |
| Object lock = new Object(); |
| synchronized (lock) { |
| assertTrue("lock should be held", Thread.holdsLock(lock)); |
| try { |
| Thread.sleep(100); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| assertTrue("lock should be held after sleeping", |
| Thread.holdsLock(lock)); |
| try { |
| lock.wait(100); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| assertTrue("lock should be obtained after waiting", |
| Thread.holdsLock(lock)); |
| } |
| assertFalse("lock should not be held", Thread.holdsLock(lock)); |
| } |
| |
| /** |
| * Test for holdsLock(null) |
| */ |
| public void testHoldsLock_Null() { |
| try { |
| Thread.holdsLock(null); |
| fail("NullPointerException has not been thrown"); |
| } catch (NullPointerException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Verify that interrupt status is cleared by the interrupted() |
| */ |
| public void testInterrupted() { |
| class ThreadInterrupt extends Thread { |
| private boolean interrupted1 = false; |
| private boolean interrupted2; |
| |
| public void run() { |
| interrupt(); |
| interrupted1 = Thread.interrupted(); |
| interrupted2 = Thread.interrupted(); |
| } |
| }; |
| ThreadInterrupt t = new ThreadInterrupt(); |
| t.start(); |
| for (waitTime = waitDuration; !t.interrupted1 && !(expired = doSleep(10));) { |
| } |
| assertTrue("interrupt status has not changed to true", t.interrupted1); |
| assertFalse("interrupt status has not changed to false", t.interrupted2); |
| } |
| |
| /** |
| * Test for void sleep(long) |
| */ |
| public void testSleeplong() { |
| Object lock = new Object(); |
| long millis = 2000; |
| ThreadWaiting tW = new ThreadWaiting(Action.SLEEP, millis, 0, lock); |
| try { |
| synchronized (lock) { |
| tW.start(); |
| while (!tW.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| try { |
| tW.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| long duration = tW.getEndTime() - tW.getStartTime(); |
| // we allow the test to wait 2.5% less |
| long atLeast = millis - 50; |
| assertTrue("thread has not slept enough: expected " + atLeast |
| + " but was " + duration, |
| duration >= atLeast); |
| } |
| |
| /** |
| * Test for void sleep(long, int) |
| */ |
| public void testSleeplongint() { |
| Object lock = new Object(); |
| long millis = 2000; |
| int nanos = 123456; |
| ThreadWaiting tW = new ThreadWaiting(Action.SLEEP, millis, nanos, lock); |
| try { |
| synchronized (lock) { |
| tW.start(); |
| while (!tW.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| try { |
| tW.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| long duration = tW.getEndTime() - tW.getStartTime(); |
| duration *= 1000000; // nano |
| // we allow the test to wait 2.5% less |
| long atLeast = (millis - 50) * 1000000; |
| assertTrue("thread has not slept enough: expected " + atLeast |
| + " but was " + duration, |
| duration >= atLeast); |
| } |
| |
| /** |
| * Test for void yield() |
| */ |
| public void testYield() { |
| ThreadYielding t1 = new ThreadYielding(1); |
| ThreadYielding t2 = new ThreadYielding(2); |
| t1.start(); |
| t2.start(); |
| try { |
| t1.join(); |
| t2.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| int oneCount = 0; |
| int threadNum = ThreadYielding.dim; |
| for (int i = 0; i < threadNum; i++) { |
| if (ThreadYielding.list[i] == 1) { |
| oneCount++; |
| } |
| } |
| // We suppose that threads t1 and t2 alternate with each other. |
| // The might be a case when some another thread (not t2) runs |
| // while t1 is yelding. In this case the 'list' might start with 1s |
| // and end with 2s and look like threads does not alternate. |
| // We cannot treat this as failure nevertheless. |
| // We just make sure that both threads have finished successfully. |
| assertTrue("threads have not finished successfully", |
| oneCount == threadNum / 2); |
| } |
| |
| /** |
| * Test for checkAccess when there is a SecurityManager |
| */ |
| public void testCheckAccess() { |
| SecurityManager sm = System.getSecurityManager(); |
| System.setSecurityManager(new ReversibleSecurityManager()); |
| Thread t = new Thread(); |
| try { |
| t.checkAccess(); |
| } finally { |
| System.setSecurityManager(sm); |
| } |
| } |
| |
| public void testDestroy() { |
| Thread t = new Thread(); |
| try { |
| t.destroy(); |
| fail("the destroy method should not be implemented"); |
| } catch (NoSuchMethodError er) { |
| return; |
| } |
| } |
| |
| /** |
| * Get context ClassLoader of a newly created thread |
| */ |
| public void testGetContextClassLoader() { |
| Thread t = new Thread(); |
| assertSame("improper ClassLoader", |
| Thread.currentThread().getContextClassLoader(), |
| t.getContextClassLoader()); |
| } |
| |
| /** |
| * Get context ClassLoader of main thread |
| */ |
| public void testGetContextClassLoader_Main() { |
| ClassLoader cl = null; |
| |
| // find the root ThreadGroup |
| ThreadGroup parent = new ThreadGroup(Thread.currentThread().getThreadGroup(), |
| "Temporary"); |
| ThreadGroup newParent = parent.getParent(); |
| while (newParent != null) { |
| parent = newParent; |
| newParent = parent.getParent(); |
| } |
| |
| // enumerate threads and select "main" thread |
| int threadsCount = parent.activeCount() + 1; |
| int count; |
| Thread[] liveThreads; |
| while (true) { |
| liveThreads = new Thread[threadsCount]; |
| count = parent.enumerate(liveThreads); |
| if (count == threadsCount) { |
| threadsCount *= 2; |
| } else { |
| break; |
| } |
| } |
| for (int i = 0; i < count; i++) { |
| if (liveThreads[i].toString().indexOf("ain]") > 0) { |
| cl = liveThreads[i].getContextClassLoader(); |
| break; |
| } |
| } |
| assertSame("improper ClassLoader", cl, ClassLoader.getSystemClassLoader()); |
| } |
| |
| /** |
| * Check that IDs of different threads differ |
| */ |
| public void testGetIdUnique() { |
| Thread t1 = new Thread("thread1"); |
| Thread t2 = new Thread("thread2"); |
| assertTrue("Thread id must be unique", t1.getId() != t2.getId()); |
| } |
| |
| /** |
| * Check that ID of a thread does not change |
| */ |
| public void testGetIdUnchanged() { |
| ThreadRunning t1 = new ThreadRunning(); |
| long tIdNew = t1.getId(); |
| t1.start(); |
| waitTime = waitDuration; |
| while (t1.i == 0 && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("thread has not started"); |
| } |
| long tIdRun = t1.getId(); |
| assertEquals("Thread ID after start should not change", tIdNew, tIdRun); |
| t1.stopWork = true; |
| try { |
| t1.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| long tIdTerm = t1.getId(); |
| assertEquals("Thread ID after termination should not change", tIdRun, tIdTerm); |
| } |
| |
| /** |
| * Verify the getName() method for a thread created with the default name. |
| * It should start with "Thread-". |
| */ |
| public void testGetNameDefault() { |
| Thread t = new Thread(); |
| String name = t.getName(); |
| assertEquals("Thread name must start with 'Thread-'", 0, name.indexOf("Thread-")); |
| } |
| |
| /** |
| * Verify the getName() method for a thread created with the given name. |
| */ |
| public void testGetName() { |
| Thread t = new Thread("newThread"); |
| String name = t.getName(); |
| assertEquals("newThread", name); |
| } |
| |
| /** |
| * Verify the getPriority() method for a newly created thread. |
| */ |
| public void testGetPriority() { |
| Thread t = new Thread(); |
| int p = t.getPriority(); |
| assertTrue("The thread's priority is out of range", |
| Thread.MIN_PRIORITY <= p && p <= Thread.MAX_PRIORITY); |
| } |
| |
| /** |
| * Get the stack trace of a thread. |
| * Should be empty for new and terminated threads. |
| * Should not be empty for running threads. |
| */ |
| public void testGetStackTrace() { |
| ThreadRunning tR = new ThreadRunning(); |
| |
| // get stack trace of a new thread |
| StackTraceElement ste[] = tR.getStackTrace(); |
| assertEquals("stack dump of a new thread is not empty", ste.length, 0); |
| tR.start(); |
| |
| // get stack trace of a running thread |
| waitTime = waitDuration; |
| do { |
| ste = tR.getStackTrace(); |
| } while (ste.length == 0 && !(expired = doSleep(10))); |
| if (expired) { |
| fail("stack dump of a running thread is empty"); |
| } else { |
| assertTrue("incorrect length", ste.length >= 1); |
| /* |
| // commented: sometimes it returns Thread.runImpl |
| assertEquals("incorrect class name", |
| "java.lang.ThreadTest$ThreadRunning", |
| ste[0].getClassName()); |
| assertEquals("incorrect method name", |
| "run", ste[0].getMethodName()); |
| */ |
| } |
| |
| // get stack trace of a terminated thread |
| tR.stopWork = true; |
| try { |
| tR.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| waitTime = waitDuration; |
| do { |
| ste = tR.getStackTrace(); |
| } while (ste.length != 0 && !(expired = doSleep(10))); |
| if (expired) { |
| fail("stack dump of a terminated thread is not empty"); |
| } |
| } |
| |
| /** |
| * Verify getAllStackTraces() |
| */ |
| public void testGetAllStackTraces() { |
| StackTraceElement ste[] = null; |
| ThreadRunning tR = new ThreadRunning("MyThread"); |
| tR.start(); |
| |
| Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces(); |
| tR.stopWork = true; |
| assertTrue("getAllStackTraces() returned an empty Map", m.size() > 0); |
| |
| // verify stack traces of all threads |
| Set<Thread> threadSet = m.keySet(); |
| for (Thread t : threadSet) { |
| ste = m.get(t); |
| assertNotNull("improper stack trace for thread " + t, ste); |
| } |
| } |
| |
| /** |
| * Get the thread group of a thread created in the current thread's |
| * thread group. |
| */ |
| public void testGetThreadGroup() { |
| Thread t = new Thread(); |
| ThreadGroup threadGroup = t.getThreadGroup(); |
| ThreadGroup curThreadGroup = Thread.currentThread().getThreadGroup(); |
| assertEquals("incorrect value returned by getThreadGroup()", |
| curThreadGroup, threadGroup); |
| } |
| |
| /** |
| * Get the thread group of a thread created in the specified thread group. |
| */ |
| public void testGetThreadGroup1() { |
| ThreadGroup tg = new ThreadGroup("group1"); |
| Thread t = new Thread(tg, "t1"); |
| ThreadGroup threadGroup = t.getThreadGroup(); |
| assertEquals("incorrect value returned by getThreadGroup()", |
| tg, threadGroup); |
| } |
| |
| /** |
| * Get the thread group of a dead thread. |
| */ |
| public void testGetThreadGroup_DeadThread() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| assertNull("Thread group of a dead thread must be null", |
| t.getThreadGroup()); |
| } |
| |
| /** |
| * Get the state of a blocked thread. |
| */ |
| public void testGetStateBlocked() { |
| Team team = new Team(); |
| RunProject pr1 = new RunProject(team); |
| pr1.start(); |
| waitTime = waitDuration; |
| while (team.i == 0 && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("pr1 has not been started"); |
| } |
| RunProject pr2 = new RunProject(team); |
| pr2.start(); |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = pr2.getState(); |
| } while (!state.equals(Thread.State.BLOCKED) && !(expired = doSleep(10))); |
| team.stopWork(); |
| if (expired) { |
| fail("BLOCKED state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a new thread. |
| */ |
| public void testGetStateNew() { |
| ThreadRunning tR = new ThreadRunning(); |
| Thread.State state = tR.getState(); |
| assertEquals(Thread.State.NEW, state); |
| } |
| |
| /** |
| * Get the state of a new thread. |
| */ |
| public void testGetStateNew1() { |
| Square s = new Square(15); |
| Thread t = new Thread(s); |
| assertEquals(Thread.State.NEW, t.getState()); |
| } |
| |
| /** |
| * Get the state of a runnable thread. |
| */ |
| public void testGetStateRunnable() { |
| ThreadRunning tR = new ThreadRunning(); |
| tR.start(); |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = tR.getState(); |
| } while (!state.equals(Thread.State.RUNNABLE) && !(expired = doSleep(10))); |
| tR.stopWork = true; |
| if (expired) { |
| fail("RUNNABLE state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a runnable thread. |
| */ |
| public void testGetStateRunnable1() { |
| Square s = new Square(15); |
| Thread t = new Thread(s); |
| t.start(); |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = t.getState(); |
| } while (!state.equals(Thread.State.RUNNABLE) && !(expired = doSleep(10))); |
| s.stop = true; |
| if (expired) { |
| fail("RUNNABLE state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a terminated thread. |
| */ |
| public void testGetStateTerminated() { |
| ThreadRunning tR = new ThreadRunning(); |
| tR.start(); |
| tR.stopWork = true; |
| try { |
| tR.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = tR.getState(); |
| } while (!state.equals(Thread.State.TERMINATED) && !(expired = doSleep(10))); |
| if (expired) { |
| fail("TERMINATED state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a terminated thread. |
| */ |
| public void testGetStateTerminated1() { |
| Square s = new Square(15); |
| Thread tR = new Thread(s); |
| tR.start(); |
| s.stop = true; |
| try { |
| tR.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| Thread.State state = tR.getState(); |
| waitTime = waitDuration; |
| while (!state.equals(Thread.State.TERMINATED) && !(expired = doSleep(10))) { |
| state = tR.getState(); |
| } |
| if (expired) { |
| fail("TERMINATED state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a timed waiting thread. |
| */ |
| public void testGetStateTimedWaiting() { |
| Object lock = new Object(); |
| ThreadWaiting tW = new ThreadWaiting(Action.WAIT, 6000, 0, lock); |
| try { |
| synchronized (lock) { |
| tW.start(); |
| while (!tW.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = tW.getState(); |
| } while (!state.equals(Thread.State.TIMED_WAITING) && !(expired = doSleep(10))); |
| synchronized (tW) { |
| tW.notify(); |
| } |
| if (expired) { |
| fail("TIMED_WAITING state has not been set"); |
| } |
| } |
| |
| /** |
| * Get the state of a waiting thread. |
| */ |
| public void testGetStateWaiting() { |
| Object lock = new Object(); |
| ThreadWaiting tW = new ThreadWaiting(Action.WAIT, 0, 0, lock); |
| try { |
| synchronized (lock) { |
| tW.start(); |
| while (!tW.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = tW.getState(); |
| } while (!state.equals(Thread.State.WAITING) && !(expired = doSleep(10))); |
| synchronized (tW) { |
| tW.notify(); |
| } |
| if (expired) { |
| fail("WAITING state has not been set"); |
| } |
| } |
| |
| class ExceptionHandler implements Thread.UncaughtExceptionHandler { |
| |
| public boolean wasCalled = false; |
| |
| public void uncaughtException(Thread t, Throwable e) { |
| wasCalled = true; |
| } |
| } |
| |
| /** |
| * Test for getUncaughtExceptionHandler() |
| */ |
| public void testGetUncaughtExceptionHandler() { |
| ThreadGroup tg = new ThreadGroup("test thread group"); |
| Thread t = new Thread(tg, "test thread"); |
| Thread.UncaughtExceptionHandler hndlr = t.getUncaughtExceptionHandler(); |
| assertSame("Thread's thread group is expected to be a handler", |
| tg, hndlr); |
| } |
| |
| /** |
| * Test getUncaughtExceptionHandler() for a terminated thread |
| */ |
| public void testGetUncaughtExceptionHandler_Null() { |
| ThreadGroup tg = new ThreadGroup("test thread group"); |
| Thread t = new Thread(tg, "test thread"); |
| t.start(); |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| Thread.State state; |
| waitTime = waitDuration; |
| do { |
| state = t.getState(); |
| } while (!state.equals(Thread.State.TERMINATED) && !(expired = doSleep(10))); |
| if (expired) { |
| fail("TERMINATED state has not been set"); |
| } |
| assertNull("handler should be null for a terminated thread", |
| t.getUncaughtExceptionHandler()); |
| } |
| |
| /** |
| * Test for setUncaughtExceptionHandler() |
| */ |
| public void testSetUncaughtExceptionHandler() { |
| ThreadGroup tg = new ThreadGroup("test thread group"); |
| Thread t = new Thread(tg, "test thread"); |
| ExceptionHandler eh = new ExceptionHandler(); |
| t.setUncaughtExceptionHandler(eh); |
| assertSame("the handler has not been set", |
| eh, t.getUncaughtExceptionHandler()); |
| } |
| |
| /** |
| * Test for setUncaughtExceptionHandler(null) |
| */ |
| public void testSetUncaughtExceptionHandler_Null() { |
| ThreadGroup tg = new ThreadGroup("test thread group"); |
| Thread t = new Thread(tg, "test thread"); |
| t.setUncaughtExceptionHandler(null); |
| assertSame("Thread's thread group is expected to be a handler", |
| tg, t.getUncaughtExceptionHandler()); |
| } |
| |
| /** |
| * Test set/get DefaultUncaughtExceptionHandler() |
| */ |
| public void testSetDefaultUncaughtExceptionHandler() { |
| ExceptionHandler eh = new ExceptionHandler(); |
| Thread.setDefaultUncaughtExceptionHandler(eh); |
| assertSame("the default handler has not been set", |
| eh, Thread.getDefaultUncaughtExceptionHandler()); |
| } |
| |
| /** |
| * Test set/get DefaultUncaughtExceptionHandler(null) |
| */ |
| public void testSetDefaultUncaughtExceptionHandler_Null() { |
| Thread.setDefaultUncaughtExceptionHandler(null); |
| assertNull("default handler should be null", |
| Thread.getDefaultUncaughtExceptionHandler()); |
| } |
| |
| /** |
| * Interrupt a newly created thread |
| */ |
| public void testInterrupt_New() { |
| Thread t = new Thread(); |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.isInterrupted() && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("interrupt status has not changed to true"); |
| } |
| } |
| |
| /** |
| * Interrupt a running thread |
| */ |
| public void testInterrupt_RunningThread() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| waitTime = waitDuration; |
| while (t.i == 0 && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("unexpected: thread's run() method has not started"); |
| } |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.isInterrupted() && !(expired = doSleep(10))) { |
| } |
| t.stopWork = true; |
| if (expired) { |
| fail("interrupt status has not changed to true"); |
| } |
| } |
| |
| /** |
| * Interrupt the current thread |
| */ |
| public void testInterrupt_CurrentThread() { |
| Thread t = new Thread() { |
| public void run() { |
| interrupt(); |
| } |
| }; |
| t.start(); |
| waitTime = waitDuration; |
| while (!t.isInterrupted() && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("interrupt status has not changed to true"); |
| } |
| } |
| |
| /** |
| * Interrupt a terminated thread |
| */ |
| public void testInterrupt_Terminated() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| waitTime = waitDuration; |
| while (t.i == 0 && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("thread' run() method has not started"); |
| } |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| t.interrupt(); |
| assertTrue("interrupt status has not changed to true", |
| t.isInterrupted()); |
| } |
| |
| /** |
| * Interrupt a joining thread |
| */ |
| public void testInterrupt_Joining() { |
| Object lock = new Object(); |
| ThreadWaiting t = new ThreadWaiting(Action.JOIN, 10000, 0, lock); |
| try { |
| synchronized (lock) { |
| t.start(); |
| while (!t.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.exceptionReceived && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("joining thread has not received the InterruptedException"); |
| } |
| assertFalse("interrupt status has not been cleared", |
| t.isInterrupted()); |
| } |
| |
| /** |
| * Interrupt a sleeping thread |
| */ |
| public void testInterrupt_Sleeping() { |
| Object lock = new Object(); |
| ThreadWaiting t = new ThreadWaiting(Action.SLEEP, 10000, 0, lock); |
| try { |
| synchronized (lock) { |
| t.start(); |
| while (!t.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| waitTime = waitDuration; |
| while (!t.isAlive() && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("thread has not started for " + waitDuration + "ms"); |
| } |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.exceptionReceived && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("sleeping thread has not received the InterruptedException"); |
| } |
| assertFalse("interrupt status has not been cleared", |
| t.isInterrupted()); |
| } |
| |
| /** |
| * Interrupt a waiting thread |
| */ |
| public void testInterrupt_Waiting() { |
| Object lock = new Object(); |
| ThreadWaiting t = new ThreadWaiting(Action.WAIT, 10000, 0, lock); |
| try { |
| synchronized (lock) { |
| t.start(); |
| while (!t.started) { |
| lock.wait(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| waitTime = waitDuration; |
| Thread.State ts = t.getState(); |
| while (ts != Thread.State.TIMED_WAITING && !(expired = doSleep(10))) { |
| ts = t.getState(); |
| } |
| if (expired) { |
| fail("TIMED_WAITING state has not been reached"); |
| } |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.exceptionReceived && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("waiting thread has not received the InterruptedException"); |
| } |
| assertFalse("interrupt status has not been cleared", |
| t.isInterrupted()); |
| } |
| |
| static final int COUNT = 100; |
| volatile int base; |
| |
| /** |
| * Check that interrupt and notify happen exactly once for each |
| * <code>notify()</code> and <code>interrupt()</code> call. |
| */ |
| public void testInterrupt_Staging() { |
| ThreadStaging t = new ThreadStaging(); |
| |
| base = 0; |
| t.start(); |
| |
| try { |
| for (base = 0; base < COUNT; ) { |
| synchronized (t) { |
| t.waitStage("notify"); |
| t.notify(); |
| |
| t.waitStage("interrupt"); |
| t.interrupt(); |
| } |
| } |
| } catch (InterruptedException e) { |
| fail("Unexpected exception: " + e); |
| } |
| } |
| |
| private class ThreadStaging extends Thread { |
| static final long TIMEOUT = 100; |
| int stage; |
| |
| public void run() { |
| for (stage = 0; stage < COUNT; ) { |
| |
| try { |
| waitBase(); |
| } catch (InterruptedException e) { |
| fail("Unexpected exception: " + e); |
| } |
| assertEquals("Stages are not synchronized after interrupt", stage, base); |
| |
| try { |
| waitBase(); |
| fail("The thread should be interrupted"); |
| } catch (InterruptedException e) { |
| assertEquals("Stages are not synchronized after interrupt", stage, base); |
| continue; |
| } |
| fail("The thread should be interrupted by (InterruptedException"); |
| } |
| } |
| |
| public synchronized void waitStage(String stageName) throws InterruptedException { |
| for (int i = 0; (base == stage) && (i < COUNT); i++) { |
| wait(TIMEOUT); |
| } |
| assertEquals("waitFor " + stageName + ": stages are not synchronized before", stage, ++base); |
| } |
| |
| synchronized void waitBase() throws InterruptedException { |
| stage++; |
| notify(); |
| wait(TIMEOUT); |
| } |
| } |
| |
| /** |
| * Verify that the current thread is alive |
| */ |
| public void testIsAliveCurrent() { |
| assertTrue("The current thread must be alive!", Thread.currentThread().isAlive()); |
| } |
| |
| /** |
| * Verify that a thread is alive just after start |
| */ |
| public void testIsAlive() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| assertTrue("The started thread must be alive!", t.isAlive()); |
| t.stopWork = true; |
| } |
| |
| /** |
| * Verify the isAlive() method for a newly created, running |
| * and finished thread |
| */ |
| public void testIsAlive1() { |
| TestThread t = new TestThread(); |
| assertFalse("Newly created and not started thread must not be alive!", |
| t.isAlive()); |
| try { |
| synchronized (t) { |
| t.start(); |
| t.wait(); |
| } |
| if (!t.isAlive()) { |
| if (t.e != null) { |
| fail("The thread was interrupted"); |
| } |
| fail("The thread must be alive"); |
| } |
| synchronized (t) { |
| t.notify(); |
| } |
| waitTime = waitDuration; |
| while (t.isAlive() && !(expired = doSleep(10))) { |
| t.join(); |
| } |
| if (expired) { |
| fail("thread has not finished for " + waitDuration + "ms"); |
| } |
| } catch (InterruptedException e) { |
| fail("Current thread was interrupted"); |
| } |
| } |
| |
| /** |
| * Verify the isAlive() method for a few threads |
| */ |
| public void testIsAlive2() { |
| ThreadRunning t1 = new ThreadRunning(); |
| ThreadRunning t2 = new ThreadRunning(); |
| ThreadRunning t3 = new ThreadRunning(); |
| assertFalse("t1 has not started and must not be alive", t1.isAlive()); |
| assertFalse("t2 has not started and must not be alive", t2.isAlive()); |
| assertFalse("t3 has not started and must not be alive", t3.isAlive()); |
| t1.start(); |
| t2.start(); |
| t3.start(); |
| assertTrue("t1 must be alive", t1.isAlive()); |
| assertTrue("t2 must be alive", t2.isAlive()); |
| assertTrue("t3 must be alive", t3.isAlive()); |
| t1.stopWork = true; |
| t2.stopWork = true; |
| t3.stopWork = true; |
| try { |
| t1.join(); |
| t2.join(); |
| t3.join(); |
| } catch (InterruptedException e) { |
| fail("threads have been interrupted"); |
| } |
| assertFalse("t1 has finished and must not be alive", t1.isAlive()); |
| assertFalse("t2 has finished and must not be alive", t2.isAlive()); |
| assertFalse("t3 has finished and must not be alive", t3.isAlive()); |
| } |
| |
| public void testIsDaemonFalse() { |
| Thread t = new Thread(); |
| assertFalse("thread should not be daemon", t.isDaemon()); |
| } |
| |
| public void testIsDaemonTrue() { |
| Thread t = new Thread(); |
| t.setDaemon(true); |
| assertTrue("thread should be daemon", t.isDaemon()); |
| } |
| |
| /** |
| * Check that interrupt status is not affected by isInterrupted() |
| */ |
| public void testIsInterrupted() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| waitTime = waitDuration; |
| while (t.i == 0 && !(expired = doSleep(10))) { |
| } |
| if (expired) { |
| fail("unexpected: thread's run() method has not started"); |
| } |
| t.interrupt(); |
| waitTime = waitDuration; |
| while (!t.isInterrupted() && !(expired = doSleep(10))) { |
| } |
| t.stopWork = true; |
| if (expired) { |
| fail("interrupt status has not changed to true"); |
| } |
| assertTrue("interrupt status has been cleared by the previous call", |
| t.isInterrupted()); |
| } |
| |
| /** |
| * Test for void join(long) |
| */ |
| public void testJoinlong() { |
| long millis = 2000; |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| long joinStartTime = 0; |
| long curTime = 0; |
| try { |
| joinStartTime = System.currentTimeMillis(); |
| t.join(millis); |
| curTime = System.currentTimeMillis(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| long duration = curTime - joinStartTime; |
| // we allow the test to wait 2.5% less |
| long atLeast = (millis - 50); |
| t.stopWork = true; |
| assertTrue("join should wait for at least " + atLeast + |
| " but waited for " + duration, |
| duration >= atLeast); |
| } |
| |
| /** |
| * Test for void join(long, int) |
| */ |
| public void testJoinlongint() { |
| long millis = 2000; |
| int nanos = 999999; |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| long joinStartTime = 0; |
| long curTime = 0; |
| try { |
| joinStartTime = System.currentTimeMillis(); |
| t.join(millis, nanos); |
| curTime = System.currentTimeMillis(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| long duration = 1000000 * (curTime - joinStartTime); |
| // we allow the test to wait 2.5% less |
| long atLeast = (millis - 50) * 1000000 + nanos; |
| t.stopWork = true; |
| assertTrue("join should wait for at least " + atLeast + |
| " but waited for " + duration, |
| duration >= atLeast); |
| } |
| |
| /** |
| * Test for run(). Should do nothing. |
| */ |
| public void testRun() { |
| Thread t = new Thread(); |
| Thread.State tsBefore = t.getState(); |
| t.run(); |
| Thread.State tsAfter = t.getState(); |
| assertEquals("run() should do nothing", tsBefore, tsAfter); |
| } |
| |
| /** |
| * Test for run(). Should call run() of a Runnable object. |
| */ |
| public void testRun_Runnable() { |
| Square s = new Square(25, true); |
| Thread t = new Thread(s); |
| t.run(); |
| assertEquals("thread has not run", 625, s.squaredNumber); |
| } |
| |
| public void testSetContextClassLoader() { |
| Class c = null; |
| try { |
| c = Class.forName("java.lang.String"); |
| } catch (ClassNotFoundException e) { |
| fail("ClassNotFoundException for java.lang.String"); |
| } |
| ClassLoader cl = c.getClassLoader(); |
| ThreadRunningAnotherThread t = new ThreadRunningAnotherThread(); |
| ClassLoader clt = t.getContextClassLoader(); |
| t.setContextClassLoader(cl); |
| ClassLoader clNew = t.getContextClassLoader(); |
| assertSame("incorrect ClassLoader has been set", |
| cl, clNew); |
| assertNotSame("ClassLoader has not changed", clt, clNew); |
| } |
| |
| /** |
| * Make a thread daemon |
| */ |
| public void testSetDaemon() { |
| Thread t = new Thread(); |
| assertFalse("Assert 0: the newly created thread must not be daemon", |
| t.isDaemon()); |
| t.setDaemon(true); |
| assertTrue("Assert 1: the thread must be daemon", t.isDaemon()); |
| } |
| |
| /** |
| * Try to make a running thread daemon |
| */ |
| public void testSetDaemonLiveThread() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| try { |
| t.setDaemon(true); |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| fail("IllegalThreadStateException has not been thrown"); |
| } catch (IllegalThreadStateException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Make a dead thread daemon |
| */ |
| public void testSetDaemonDeadThread() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| boolean threadDaemonStatus = t.isDaemon(); |
| try { |
| t.setDaemon(!threadDaemonStatus); |
| } catch (IllegalThreadStateException e) { |
| fail("IllegalThreadStateException should not be thrown" |
| + " for a dead thread"); |
| } |
| } |
| |
| /** |
| * Verify the setName() method |
| */ |
| public void testSetName() { |
| Thread thread = new Thread(); |
| String newName = "qwerty"; |
| thread.setName(newName); |
| assertEquals("setName() has not set the new name", |
| newName, thread.getName()); |
| } |
| |
| /** |
| * Verify the setName(null) method |
| */ |
| public void testSetNameNull() { |
| Thread thread = new Thread(); |
| try { |
| thread.setName(null); |
| } catch (NullPointerException e) { |
| return; |
| } |
| fail("setName() should not accept null names"); |
| } |
| |
| /** |
| * Verify the setName() method when a SecurityManager is set. |
| */ |
| public void testSetName_CheckAccess() { |
| sm = System.getSecurityManager(); |
| System.setSecurityManager(new ReversibleSecurityManager()); |
| Thread thread = new Thread(); |
| String newName = "qwerty"; |
| thread.setName(newName); |
| String gotName = thread.getName(); |
| System.setSecurityManager(sm); |
| assertEquals("setName() has not set the new name", |
| newName, gotName); |
| } |
| |
| /** |
| * Verify the setPriority() method to a dead thread. |
| * NullPointerException is expected |
| */ |
| public void testSetPriorityDeadThread() { |
| ThreadGroup tg = new ThreadGroup("group1"); |
| int maxTGPriority = Thread.MAX_PRIORITY - 1; |
| tg.setMaxPriority(maxTGPriority); |
| ThreadRunning t = new ThreadRunning(tg, "running"); |
| t.start(); |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| int newPriority = Thread.MAX_PRIORITY; |
| try { |
| t.setPriority(newPriority); |
| fail("NullPointerException has not been thrown"); |
| } catch (NullPointerException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Verify the setPriority() method with new priority higher |
| * than the maximum permitted priority for the thread's group. |
| */ |
| public void testSetPriorityGreaterMax() { |
| ThreadGroup tg = new ThreadGroup("group1"); |
| int maxTGPriority = Thread.MAX_PRIORITY - 1; |
| tg.setMaxPriority(maxTGPriority); |
| Thread t = new Thread(tg, "t"); |
| t.setPriority(Thread.MAX_PRIORITY); |
| assertEquals(maxTGPriority, t.getPriority()); |
| } |
| |
| /** |
| * Verify the setPriority() method with new priority lower |
| * than the current one. |
| */ |
| public void testSetPriorityLower() { |
| Thread t = new Thread(); |
| int p = t.getPriority(); |
| int newPriority = p - 1; |
| if (newPriority >= Thread.MIN_PRIORITY) { |
| t.setPriority(newPriority); |
| assertEquals(newPriority, t.getPriority()); |
| } |
| } |
| |
| /** |
| * Verify the setPriority() method with new priority out of the legal range. |
| */ |
| public void testSetPriorityOutOfRange() { |
| Thread t = new Thread(); |
| try { |
| t.setPriority(Thread.MAX_PRIORITY + 2); |
| fail("IllegalArgumentException should be thrown when setting " |
| + "illegal priority"); |
| } catch (IllegalArgumentException e) { |
| return; |
| } |
| } |
| |
| /** |
| * Verify the setPriority() method when a SecurityManager is set. |
| */ |
| public void testSetPriority_CheckAccess() { |
| sm = System.getSecurityManager(); |
| System.setSecurityManager(new ReversibleSecurityManager()); |
| Thread t = new Thread(); |
| int p = t.getPriority(); |
| t.setPriority(p); |
| int newP = t.getPriority(); |
| System.setSecurityManager(sm); |
| assertEquals(p, newP); |
| } |
| |
| /** |
| * Start the already started thread |
| */ |
| public void testStart_Started() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| try { |
| t.start(); |
| t.stopWork = true; |
| fail("IllegalThreadStateException is expected when starting " + |
| "a started thread"); |
| } catch (IllegalThreadStateException e) { |
| t.stopWork = true; |
| } |
| } |
| |
| /** |
| * Start the already finished thread |
| */ |
| public void testStart_Finished() { |
| ThreadRunning t = new ThreadRunning(); |
| t.start(); |
| t.stopWork = true; |
| try { |
| t.join(); |
| } catch (InterruptedException e) { |
| fail(INTERRUPTED_MESSAGE); |
| } |
| try { |
| t.start(); |
| fail("IllegalThreadStateException is expected when starting " + |
| "a finished thread"); |
| } catch (IllegalThreadStateException e) { |
| return; |
| } |
| } |
| } |