Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4168811

(thread) ThreadGroup is not empty after last Thread dies

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Cannot Reproduce
    • Affects Version/s: 1.2.0
    • Fix Version/s: None
    • Component/s: core-libs
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_nt

      Description

      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.


      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                psoper Pete Soper (Inactive)
                Reporter:
                rfqsunw Rfq Rfq (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: