home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 January / PCO0198.ISO / 1&1 / java.z / java_301 / java / lang / ThreadGroup.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-10-20  |  7.6 KB  |  417 lines

  1. package java.lang;
  2.  
  3. import java.io.PrintStream;
  4.  
  5. public class ThreadGroup {
  6.    ThreadGroup parent;
  7.    String name;
  8.    int maxPriority;
  9.    boolean destroyed;
  10.    boolean daemon;
  11.    int nthreads;
  12.    Thread[] threads;
  13.    int ngroups;
  14.    ThreadGroup[] groups;
  15.  
  16.    private ThreadGroup() {
  17.       this.name = "system";
  18.       this.maxPriority = 10;
  19.    }
  20.  
  21.    public ThreadGroup(String name) {
  22.       this(Thread.currentThread().getThreadGroup(), name);
  23.    }
  24.  
  25.    public ThreadGroup(ThreadGroup parent, String name) {
  26.       if (parent == null) {
  27.          throw new NullPointerException();
  28.       } else {
  29.          parent.checkAccess(1);
  30.          this.name = name;
  31.          this.maxPriority = parent.maxPriority;
  32.          this.daemon = parent.daemon;
  33.          this.parent = parent;
  34.          parent.add(this);
  35.       }
  36.    }
  37.  
  38.    public final String getName() {
  39.       return this.name;
  40.    }
  41.  
  42.    public final ThreadGroup getParent() {
  43.       return this.parent;
  44.    }
  45.  
  46.    public final int getMaxPriority() {
  47.       return this.maxPriority;
  48.    }
  49.  
  50.    public final boolean isDaemon() {
  51.       return this.daemon;
  52.    }
  53.  
  54.    public final void setDaemon(boolean daemon) {
  55.       SecurityManager.checksAccess(this, 1);
  56.       this.daemon = daemon;
  57.    }
  58.  
  59.    public final synchronized void setMaxPriority(int pri) {
  60.       SecurityManager.checksAccess(this, 1);
  61.       if (pri < 1) {
  62.          this.maxPriority = 1;
  63.       } else if (pri < this.maxPriority) {
  64.          this.maxPriority = pri;
  65.       }
  66.  
  67.       for(int i = 0; i < this.ngroups; ++i) {
  68.          this.groups[i].setMaxPriority(pri);
  69.       }
  70.  
  71.    }
  72.  
  73.    public final boolean parentOf(ThreadGroup g) {
  74.       while(g != null) {
  75.          if (g == this) {
  76.             return true;
  77.          }
  78.  
  79.          g = g.parent;
  80.       }
  81.  
  82.       return false;
  83.    }
  84.  
  85.    public final void checkAccess(int caller_depth) {
  86.       SecurityManager.checksAccess(this, caller_depth + 1);
  87.    }
  88.  
  89.    public synchronized int activeCount() {
  90.       if (this.destroyed) {
  91.          return 0;
  92.       } else {
  93.          ThreadGroup group = this.enumeratableThreadGroup();
  94.          return group == null ? 0 : group.activeCount0();
  95.       }
  96.    }
  97.  
  98.    private int activeCount0() {
  99.       if (this.destroyed) {
  100.          return 0;
  101.       } else {
  102.          int n = this.nthreads;
  103.  
  104.          for(int i = 0; i < this.ngroups; ++i) {
  105.             n += this.groups[i].activeCount0();
  106.          }
  107.  
  108.          return n;
  109.       }
  110.    }
  111.  
  112.    public int enumerate(Thread[] list) {
  113.       return this.enumerate(list, true);
  114.    }
  115.  
  116.    public int enumerate(Thread[] list, boolean recurse) {
  117.       ThreadGroup legal_group = this.enumeratableThreadGroup();
  118.       return legal_group != null && (recurse || this == legal_group) ? legal_group.enumerate((Thread[])list, 0, recurse) : 0;
  119.    }
  120.  
  121.    private synchronized int enumerate(Thread[] list, int n, boolean recurse) {
  122.       if (this.destroyed) {
  123.          return 0;
  124.       } else {
  125.          int nt = this.nthreads;
  126.          if (nt > list.length - n) {
  127.             nt = list.length - n;
  128.          }
  129.  
  130.          if (nt > 0) {
  131.             System.arraycopy(this.threads, 0, list, n, nt);
  132.             n += nt;
  133.          }
  134.  
  135.          if (recurse) {
  136.             for(int i = 0; i < this.ngroups; ++i) {
  137.                n = this.groups[i].enumerate(list, n, true);
  138.             }
  139.          }
  140.  
  141.          return n;
  142.       }
  143.    }
  144.  
  145.    public synchronized int activeGroupCount() {
  146.       if (this.destroyed) {
  147.          return 0;
  148.       } else {
  149.          ThreadGroup legal_group = this.enumeratableThreadGroup();
  150.          if (legal_group == null) {
  151.             return 0;
  152.          } else {
  153.             int n = 0;
  154.  
  155.             for(ThreadGroup parents = legal_group; parents != this; parents = parents.parent) {
  156.                ++n;
  157.             }
  158.  
  159.             return n + legal_group.activeGroupCount0();
  160.          }
  161.       }
  162.    }
  163.  
  164.    private int activeGroupCount0() {
  165.       if (this.destroyed) {
  166.          return 0;
  167.       } else {
  168.          int n = this.ngroups;
  169.  
  170.          for(int i = 0; i < this.ngroups; ++i) {
  171.             n += this.groups[i].activeGroupCount0();
  172.          }
  173.  
  174.          return n;
  175.       }
  176.    }
  177.  
  178.    public int enumerate(ThreadGroup[] list) {
  179.       return this.enumerate(list, true);
  180.    }
  181.  
  182.    public synchronized int enumerate(ThreadGroup[] list, boolean recurse) {
  183.       ThreadGroup legal_group = this.enumeratableThreadGroup();
  184.       if (legal_group == null) {
  185.          return 0;
  186.       } else {
  187.          int n = 0;
  188.          n = this.enumerateChildren(legal_group, list, recurse);
  189.          return !recurse && n > 0 ? n : legal_group.enumerate(list, n, recurse);
  190.       }
  191.    }
  192.  
  193.    private int enumerateChildren(ThreadGroup child, ThreadGroup[] list, boolean recurse) {
  194.       if (this == child) {
  195.          return 0;
  196.       } else {
  197.          ThreadGroup parent = child.parent;
  198.          int n = this.enumerateChildren(parent, list, recurse);
  199.          if (n < list.length && (n == 0 || recurse)) {
  200.             list[n++] = child;
  201.          }
  202.  
  203.          return n;
  204.       }
  205.    }
  206.  
  207.    private synchronized int enumerate(ThreadGroup[] list, int n, boolean recurse) {
  208.       if (this.destroyed) {
  209.          return 0;
  210.       } else {
  211.          int ng = this.ngroups;
  212.          if (ng > list.length - n) {
  213.             ng = list.length - n;
  214.          }
  215.  
  216.          if (ng > 0) {
  217.             System.arraycopy(this.groups, 0, list, n, ng);
  218.             n += ng;
  219.          }
  220.  
  221.          if (recurse) {
  222.             for(int i = 0; i < this.ngroups; ++i) {
  223.                n = this.groups[i].enumerate(list, n, true);
  224.             }
  225.          }
  226.  
  227.          return n;
  228.       }
  229.    }
  230.  
  231.    public final synchronized void stop() {
  232.       SecurityManager.checksAccess(this, 1);
  233.  
  234.       for(int i = 0; i < this.ngroups; ++i) {
  235.          this.groups[i].stop();
  236.       }
  237.  
  238.       for(int i = 0; i < this.nthreads; ++i) {
  239.          this.threads[i].stop();
  240.       }
  241.  
  242.    }
  243.  
  244.    public final synchronized void suspend() {
  245.       SecurityManager.checksAccess(this, 1);
  246.  
  247.       for(int i = 0; i < this.ngroups; ++i) {
  248.          this.groups[i].suspend();
  249.       }
  250.  
  251.       for(int i = 0; i < this.nthreads; ++i) {
  252.          this.threads[i].suspend();
  253.       }
  254.  
  255.    }
  256.  
  257.    public final synchronized void resume() {
  258.       SecurityManager.checksAccess(this, 1);
  259.  
  260.       for(int i = 0; i < this.ngroups; ++i) {
  261.          this.groups[i].resume();
  262.       }
  263.  
  264.       for(int i = 0; i < this.nthreads; ++i) {
  265.          this.threads[i].resume();
  266.       }
  267.  
  268.    }
  269.  
  270.    public final synchronized void destroy() {
  271.       SecurityManager.checksAccess(this, 1);
  272.       if (!this.destroyed && this.nthreads <= 0) {
  273.          while(this.ngroups > 0) {
  274.             this.groups[0].destroy();
  275.          }
  276.  
  277.          if (this.parent != null) {
  278.             this.destroyed = true;
  279.             this.groups = null;
  280.             this.threads = null;
  281.             this.parent.remove(this);
  282.          }
  283.  
  284.       } else {
  285.          throw new IllegalThreadStateException();
  286.       }
  287.    }
  288.  
  289.    private final synchronized void add(ThreadGroup g) {
  290.       if (this.destroyed) {
  291.          throw new IllegalThreadStateException();
  292.       } else {
  293.          SecurityManager.setScopePermission();
  294.          if (this.groups == null) {
  295.             this.groups = new ThreadGroup[4];
  296.          } else if (this.ngroups == this.groups.length) {
  297.             ThreadGroup[] newgroups = new ThreadGroup[this.ngroups * 2];
  298.             System.arraycopy(this.groups, 0, newgroups, 0, this.ngroups);
  299.             this.groups = newgroups;
  300.          }
  301.  
  302.          this.groups[this.ngroups] = g;
  303.          ++this.ngroups;
  304.       }
  305.    }
  306.  
  307.    private synchronized void remove(ThreadGroup g) {
  308.       if (!this.destroyed) {
  309.          for(int i = 0; i < this.ngroups; ++i) {
  310.             if (this.groups[i] == g) {
  311.                System.arraycopy(this.groups, i + 1, this.groups, i, --this.ngroups - i);
  312.                this.groups[this.ngroups] = null;
  313.                break;
  314.             }
  315.          }
  316.  
  317.          if (this.nthreads == 0) {
  318.             this.notifyAll();
  319.          }
  320.  
  321.          if (this.daemon && this.nthreads == 0 && this.ngroups == 0) {
  322.             SecurityManager.setScopePermission();
  323.             this.destroy();
  324.          }
  325.  
  326.       }
  327.    }
  328.  
  329.    synchronized void add(Thread t) {
  330.       if (this.destroyed) {
  331.          throw new IllegalThreadStateException();
  332.       } else {
  333.          if (this.threads == null) {
  334.             this.threads = new Thread[4];
  335.          } else if (this.nthreads == this.threads.length) {
  336.             Thread[] newthreads = new Thread[this.nthreads * 2];
  337.             System.arraycopy(this.threads, 0, newthreads, 0, this.nthreads);
  338.             this.threads = newthreads;
  339.          }
  340.  
  341.          this.threads[this.nthreads] = t;
  342.          ++this.nthreads;
  343.       }
  344.    }
  345.  
  346.    synchronized void remove(Thread t) {
  347.       if (!this.destroyed) {
  348.          for(int i = 0; i < this.nthreads; ++i) {
  349.             if (this.threads[i] == t) {
  350.                System.arraycopy(this.threads, i + 1, this.threads, i, --this.nthreads - i);
  351.                this.threads[this.nthreads] = null;
  352.                break;
  353.             }
  354.          }
  355.  
  356.          if (this.nthreads == 0) {
  357.             this.notifyAll();
  358.          }
  359.  
  360.          if (this.daemon && this.nthreads == 0 && this.ngroups == 0) {
  361.             this.destroy();
  362.          }
  363.  
  364.       }
  365.    }
  366.  
  367.    public synchronized void list() {
  368.       this.list(System.out, 0);
  369.    }
  370.  
  371.    void list(PrintStream out, int indent) {
  372.       for(int j = 0; j < indent; ++j) {
  373.          out.print(" ");
  374.       }
  375.  
  376.       out.println(this);
  377.       indent += 4;
  378.  
  379.       for(int i = 0; i < this.nthreads; ++i) {
  380.          for(int j = 0; j < indent; ++j) {
  381.             out.print(" ");
  382.          }
  383.  
  384.          out.println(this.threads[i]);
  385.       }
  386.  
  387.       for(int i = 0; i < this.ngroups; ++i) {
  388.          this.groups[i].list(out, indent);
  389.       }
  390.  
  391.    }
  392.  
  393.    public void uncaughtException(Thread t, Throwable e) {
  394.       if (this.parent != null) {
  395.          this.parent.uncaughtException(t, e);
  396.       } else {
  397.          if (!(e instanceof ThreadDeath)) {
  398.             e.printStackTrace(System.err);
  399.          }
  400.  
  401.       }
  402.    }
  403.  
  404.    public String toString() {
  405.       return this.getClass().getName() + "[name=" + this.getName() + ",maxpri=" + this.maxPriority + "]";
  406.    }
  407.  
  408.    private ThreadGroup enumeratableThreadGroup() {
  409.       ThreadGroup direct_parent = Thread.currentThread().getThreadGroup();
  410.       if (direct_parent != this && !direct_parent.parentOf(this)) {
  411.          return this.parentOf(direct_parent) ? direct_parent : null;
  412.       } else {
  413.          return this;
  414.       }
  415.    }
  416. }
  417.