Name: akC45999 Date: 08/25/98
The description of java.lang.ThreadGroup.destroy() reads:
Throws:
IllegalThreadStateException - if the thread group is not empty or if the thread group has
already been destroyed.
But in JDK1.2 FCS-G/windowsNT, the method throws IllegalThreadStateException when group
is empty and not yet destroyed.
-------------------------------------------------- file destroy10101.java
//File: @(#)destroy0101.java 1.2 98/07/02
//Copyright 07/02/98 Sun Microsystems, Inc. All Rights Reserved
//package javasoft.sqe.tests.api.java.lang.ThreadGroup.destroy0101;
import java.io.PrintStream;
import javasoft.sqe.harness.Status;
import javasoft.sqe.harness.Test;
class destroy0101t extends Thread {
destroy0101 event;
destroy0101t(destroy0101g group, destroy0101 event) {
super(group, group.groupName+".activeThrd");
this.event=event;
}
public void run() {
event.run();
}
} // end class destroy0101t
class destroy0101g extends ThreadGroup {
static final int activeNum=1; // active threads in each group
String groupName;
Thread activeThrd;
destroy0101g subgroup;
destroy0101 event;
void finish() throws InterruptedException {
if (subgroup!=null) subgroup.finish();
activeThrd.join();
}
destroy0101g(ThreadGroup parent, destroy0101 event, int level) {
super("destroy0101g_"+level);
this.event=event;
groupName="destroy0101g_"+level;
activeThrd=new destroy0101t(this, event);
activeThrd.start();
if (level>0)
subgroup=new destroy0101g(this, event, level-1);
}
} // end class destroy0101g
public class destroy0101 implements Test {
boolean end=false;
public synchronized void run() {
while (!end) {;
try {
wait();
} catch (InterruptedException e) {
}
}
}
public synchronized void stopAll() {
end=true;
notifyAll();
}
public Status run(String argv[], PrintStream log, PrintStream out) {
destroy0101g group=new destroy0101g(Thread.currentThread().getThreadGroup(), this, 5);
try {
group.destroy();
return Status.failed("no IllegalThreadStateException 1");
} catch (IllegalThreadStateException e) {
} finally {
stopAll();
}
try {
group.finish();
} catch (InterruptedException e) {
return Status.failed("InterruptedException while joining child thread.");
}
try {
group.destroy();
} catch (Throwable e) {
return Status.failed("unexpected exception:"+e);
}
if (!group.isDestroyed()) {
return Status.failed("destroy() called but group !isDestroyed()");
}
try {
group.destroy();
return Status.failed("no IllegalThreadStateException 2");
} catch (IllegalThreadStateException e) {
}
return Status.passed("");
}
public static void main(String args[]) {
(new destroy0101()).run(args, System.err, System.out).exit();
}
}
----------------------------
output:
unexpected exception: IllegalThreadStateException
======================================================================
Name: akC45999 Date: 10/06/98
A Fujitsu engeneer suggested to add a call to Thread.sleep()
between group.finish() and group.destroy() to help the test to pass.
This does work both on Windows 95 and WindowsNT.
Another test (activeCount0102) just counts active threads but behaves identically
(sleep(delay) makes the test to pass).
So I assume that a Thread Group does not become empty immediately
after the last thread dies, but some time later.
//------------------- activeCount0102.java
// simplified version of the test javasoft.sqe.tests.api.java.lang.ThreadGroup.activeCount0102
import java.io.PrintStream;
public class activeCount0102 {
public static void main(String argv[]) {
long delay=((argv.length==0)?-1:Long.parseLong(argv[0]));
ThreadGroup group=new ThreadGroup("activeCount0102_g");
Thread nonActiveThrd1;
nonActiveThrd1=new Thread(group, "activeCount0102_n");
nonActiveThrd1.start();
try {
nonActiveThrd1.join();
if (delay>=0) Thread.sleep(delay);
} catch (InterruptedException e) {
System.err.println("InterruptedException in main thread");
}
int cnt0=group.activeCount();
if (cnt0 != 0)
System.err.println("Failed: activeCount()="+cnt0);
else
System.err.println("Passed.");
}
}
//------------------- end activeCount0102.java
run it with command
java activeCount0102 <delay>
Even with delay=0, test sometimes pass.
======================================================================