1 7 8 package java.lang; 9 10 import java.io.PrintStream ; 11 import sun.misc.VM; 12 13 27 38 public 39 class ThreadGroup implements Thread.UncaughtExceptionHandler { 40 ThreadGroup parent; 41 String name; 42 int maxPriority; 43 boolean destroyed; 44 boolean daemon; 45 boolean vmAllowSuspension; 46 47 int nUnstartedThreads = 0; 48 int nthreads; 49 Thread threads[]; 50 51 int ngroups; 52 ThreadGroup groups[]; 53 54 58 private ThreadGroup() { this.name = "system"; 60 this.maxPriority = Thread.MAX_PRIORITY; 61 } 62 63 76 public ThreadGroup(String name) { 77 this(Thread.currentThread().getThreadGroup(), name); 78 } 79 80 97 public ThreadGroup(ThreadGroup parent, String name) { 98 if (parent == null) { 99 throw new NullPointerException (); 100 } 101 parent.checkAccess(); 102 this.name = name; 103 this.maxPriority = parent.maxPriority; 104 this.daemon = parent.daemon; 105 this.vmAllowSuspension = parent.vmAllowSuspension; 106 this.parent = parent; 107 parent.add(this); 108 } 109 110 116 public final String getName() { 117 return name; 118 } 119 120 136 public final ThreadGroup getParent() { 137 if (parent != null) 138 parent.checkAccess(); 139 return parent; 140 } 141 142 152 public final int getMaxPriority() { 153 return maxPriority; 154 } 155 156 165 public final boolean isDaemon() { 166 return daemon; 167 } 168 169 175 public synchronized boolean isDestroyed() { 176 return destroyed; 177 } 178 179 197 public final void setDaemon(boolean daemon) { 198 checkAccess(); 199 this.daemon = daemon; 200 } 201 202 230 public final void setMaxPriority(int pri) { 231 int ngroupsSnapshot; 232 ThreadGroup [] groupsSnapshot; 233 synchronized (this) { 234 checkAccess(); 235 if (pri < Thread.MIN_PRIORITY) { 236 maxPriority = Thread.MIN_PRIORITY; 237 } else if (pri < maxPriority) { 238 maxPriority = pri; 239 } 240 ngroupsSnapshot = ngroups; 241 if (groups != null) { 242 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 243 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 244 } else { 245 groupsSnapshot = null; 246 } 247 } 248 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 249 groupsSnapshot[i].setMaxPriority(pri); 250 } 251 } 252 253 263 public final boolean parentOf(ThreadGroup g) { 264 for (; g != null ; g = g.parent) { 265 if (g == this) { 266 return true; 267 } 268 } 269 return false; 270 } 271 272 285 public final void checkAccess() { 286 SecurityManager security = System.getSecurityManager(); 287 if (security != null) { 288 security.checkAccess(this); 289 } 290 } 291 292 305 public int activeCount() { 306 int result; 307 int ngroupsSnapshot; 310 ThreadGroup [] groupsSnapshot; 311 synchronized (this) { 312 if (destroyed) { 313 return 0; 314 } 315 result = nthreads; 316 ngroupsSnapshot = ngroups; 317 if (groups != null) { 318 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 319 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 320 } else { 321 groupsSnapshot = null; 322 } 323 } 324 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 325 result += groupsSnapshot[i].activeCount(); 326 } 327 return result; 328 } 329 330 356 public int enumerate(Thread list[]) { 357 checkAccess(); 358 return enumerate(list, 0, true); 359 } 360 361 392 public int enumerate(Thread list[], boolean recurse) { 393 checkAccess(); 394 return enumerate(list, 0, recurse); 395 } 396 397 private int enumerate(Thread list[], int n, boolean recurse) { 398 int ngroupsSnapshot = 0; 399 ThreadGroup [] groupsSnapshot = null; 400 synchronized (this) { 401 if (destroyed) { 402 return 0; 403 } 404 int nt = nthreads; 405 if (nt > list.length - n) { 406 nt = list.length - n; 407 } 408 for (int i = 0; i < nt; i++) { 409 if (threads[i].isAlive()) { 410 list[n++] = threads[i]; 411 } 412 } 413 if (recurse) { 414 ngroupsSnapshot = ngroups; 415 if (groups != null) { 416 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 417 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 418 } else { 419 groupsSnapshot = null; 420 } 421 } 422 } 423 if (recurse) { 424 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 425 n = groupsSnapshot[i].enumerate(list, n, true); 426 } 427 } 428 return n; 429 } 430 431 442 public int activeGroupCount() { 443 int ngroupsSnapshot; 444 ThreadGroup [] groupsSnapshot; 445 synchronized (this) { 446 if (destroyed) { 447 return 0; 448 } 449 ngroupsSnapshot = ngroups; 450 if (groups != null) { 451 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 452 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 453 } else { 454 groupsSnapshot = null; 455 } 456 } 457 int n = ngroupsSnapshot; 458 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 459 n += groupsSnapshot[i].activeGroupCount(); 460 } 461 return n; 462 } 463 464 490 public int enumerate(ThreadGroup list[]) { 491 checkAccess(); 492 return enumerate(list, 0, true); 493 } 494 495 525 public int enumerate(ThreadGroup list[], boolean recurse) { 526 checkAccess(); 527 return enumerate(list, 0, recurse); 528 } 529 530 private int enumerate(ThreadGroup list[], int n, boolean recurse) { 531 int ngroupsSnapshot = 0; 532 ThreadGroup [] groupsSnapshot = null; 533 synchronized (this) { 534 if (destroyed) { 535 return 0; 536 } 537 int ng = ngroups; 538 if (ng > list.length - n) { 539 ng = list.length - n; 540 } 541 if (ng > 0) { 542 System.arraycopy(groups, 0, list, n, ng); 543 n += ng; 544 } 545 if (recurse) { 546 ngroupsSnapshot = ngroups; 547 if (groups != null) { 548 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 549 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 550 } else { 551 groupsSnapshot = null; 552 } 553 } 554 } 555 if (recurse) { 556 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 557 n = groupsSnapshot[i].enumerate(list, n, true); 558 } 559 } 560 return n; 561 } 562 563 582 @Deprecated 583 public final void stop() { 584 if (stopOrSuspend(false)) 585 Thread.currentThread().stop(); 586 } 587 588 605 public final void interrupt() { 606 int ngroupsSnapshot; 607 ThreadGroup [] groupsSnapshot; 608 synchronized (this) { 609 checkAccess(); 610 for (int i = 0 ; i < nthreads ; i++) { 611 threads[i].interrupt(); 612 } 613 ngroupsSnapshot = ngroups; 614 if (groups != null) { 615 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 616 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 617 } else { 618 groupsSnapshot = null; 619 } 620 } 621 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 622 groupsSnapshot[i].interrupt(); 623 } 624 } 625 626 645 @Deprecated 646 public final void suspend() { 647 if (stopOrSuspend(true)) 648 Thread.currentThread().suspend(); 649 } 650 651 658 private boolean stopOrSuspend(boolean suspend) { 659 boolean suicide = false; 660 Thread us = Thread.currentThread(); 661 int ngroupsSnapshot; 662 ThreadGroup [] groupsSnapshot = null; 663 synchronized (this) { 664 checkAccess(); 665 for (int i = 0 ; i < nthreads ; i++) { 666 if (threads[i]==us) 667 suicide = true; 668 else if (suspend) 669 threads[i].suspend(); 670 else 671 threads[i].stop(); 672 } 673 674 ngroupsSnapshot = ngroups; 675 if (groups != null) { 676 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 677 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 678 } 679 } 680 for (int i = 0 ; i < ngroupsSnapshot ; i++) 681 suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide; 682 683 return suicide; 684 } 685 686 707 @Deprecated 708 public final void resume() { 709 int ngroupsSnapshot; 710 ThreadGroup [] groupsSnapshot; 711 synchronized (this) { 712 checkAccess(); 713 for (int i = 0 ; i < nthreads ; i++) { 714 threads[i].resume(); 715 } 716 ngroupsSnapshot = ngroups; 717 if (groups != null) { 718 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 719 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 720 } else { 721 groupsSnapshot = null; 722 } 723 } 724 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 725 groupsSnapshot[i].resume(); 726 } 727 } 728 729 744 public final void destroy() { 745 int ngroupsSnapshot; 746 ThreadGroup [] groupsSnapshot; 747 synchronized (this) { 748 checkAccess(); 749 if (destroyed || (nthreads > 0)) { 750 throw new IllegalThreadStateException (); 751 } 752 ngroupsSnapshot = ngroups; 753 if (groups != null) { 754 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 755 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 756 } else { 757 groupsSnapshot = null; 758 } 759 if (parent != null) { 760 destroyed = true; 761 ngroups = 0; 762 groups = null; 763 nthreads = 0; 764 threads = null; 765 } 766 } 767 for (int i = 0 ; i < ngroupsSnapshot ; i += 1) { 768 groupsSnapshot[i].destroy(); 769 } 770 if (parent != null) { 771 parent.remove(this); 772 } 773 } 774 775 780 private final void add(ThreadGroup g){ 781 synchronized (this) { 782 if (destroyed) { 783 throw new IllegalThreadStateException (); 784 } 785 if (groups == null) { 786 groups = new ThreadGroup [4]; 787 } else if (ngroups == groups.length) { 788 ThreadGroup newgroups[] = new ThreadGroup [ngroups * 2]; 789 System.arraycopy(groups, 0, newgroups, 0, ngroups); 790 groups = newgroups; 791 } 792 groups[ngroups] = g; 793 794 ngroups++; 797 } 798 } 799 800 805 private void remove(ThreadGroup g) { 806 synchronized (this) { 807 if (destroyed) { 808 return; 809 } 810 for (int i = 0 ; i < ngroups ; i++) { 811 if (groups[i] == g) { 812 ngroups -= 1; 813 System.arraycopy(groups, i + 1, groups, i, ngroups - i); 814 groups[ngroups] = null; 817 break; 818 } 819 } 820 if (nthreads == 0) { 821 notifyAll(); 822 } 823 if (daemon && (nthreads == 0) && 824 (nUnstartedThreads == 0) && (ngroups == 0)) 825 { 826 destroy(); 827 } 828 } 829 } 830 831 832 839 void addUnstarted() { 840 synchronized(this) { 841 if (destroyed) { 842 throw new IllegalThreadStateException (); 843 } 844 nUnstartedThreads++; 845 } 846 } 847 848 853 void add(Thread t) { 854 synchronized (this) { 855 if (destroyed) { 856 throw new IllegalThreadStateException (); 857 } 858 if (threads == null) { 859 threads = new Thread [4]; 860 } else if (nthreads == threads.length) { 861 Thread newthreads[] = new Thread [nthreads * 2]; 862 System.arraycopy(threads, 0, newthreads, 0, nthreads); 863 threads = newthreads; 864 } 865 threads[nthreads] = t; 866 867 nthreads++; 870 nUnstartedThreads--; 871 } 872 } 873 874 879 void remove(Thread t) { 880 synchronized (this) { 881 if (destroyed) { 882 return; 883 } 884 for (int i = 0 ; i < nthreads ; i++) { 885 if (threads[i] == t) { 886 System.arraycopy(threads, i + 1, threads, i, --nthreads - i); 887 threads[nthreads] = null; 890 break; 891 } 892 } 893 if (nthreads == 0) { 894 notifyAll(); 895 } 896 if (daemon && (nthreads == 0) && 897 (nUnstartedThreads == 0) && (ngroups == 0)) 898 { 899 destroy(); 900 } 901 } 902 } 903 904 910 public void list() { 911 list(System.out, 0); 912 } 913 void list(PrintStream out, int indent) { 914 int ngroupsSnapshot; 915 ThreadGroup [] groupsSnapshot; 916 synchronized (this) { 917 for (int j = 0 ; j < indent ; j++) { 918 out.print(" "); 919 } 920 out.println(this); 921 indent += 4; 922 for (int i = 0 ; i < nthreads ; i++) { 923 for (int j = 0 ; j < indent ; j++) { 924 out.print(" "); 925 } 926 out.println(threads[i]); 927 } 928 ngroupsSnapshot = ngroups; 929 if (groups != null) { 930 groupsSnapshot = new ThreadGroup [ngroupsSnapshot]; 931 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); 932 } else { 933 groupsSnapshot = null; 934 } 935 } 936 for (int i = 0 ; i < ngroupsSnapshot ; i++) { 937 groupsSnapshot[i].list(out, indent); 938 } 939 } 940 941 976 public void uncaughtException(Thread t, Throwable e) { 977 if (parent != null) { 978 parent.uncaughtException(t, e); 979 } else { 980 Thread.UncaughtExceptionHandler ueh = 981 Thread.getDefaultUncaughtExceptionHandler(); 982 if (ueh != null) { 983 ueh.uncaughtException(t, e); 984 } else if (!(e instanceof ThreadDeath )) { 985 System.err.print("Exception in thread \"" 986 + t.getName() + "\" "); 987 e.printStackTrace(System.err); 988 } 989 } 990 } 991 992 1002 @Deprecated 1003 public boolean allowThreadSuspension(boolean b) { 1004 this.vmAllowSuspension = b; 1005 if (!b) { 1006 VM.unsuspendSomeThreads(); 1007 } 1008 return true; 1009 } 1010 1011 1017 public String toString() { 1018 return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]"; 1019 } 1020} 1021 | Popular Tags |